• Main Page
  • Related Pages
  • Classes
  • Files
  • File List
  • File Members

dialog_screen.cc

Go to the documentation of this file.
00001 /*
00002    $Id: dialog_screen.cc,v 1.12 2004/10/25 06:55:01 ksterker Exp $
00003 
00004    (C) Copyright 2000/2001/2004 Kai Sterker <kaisterker@linuxgames.com>
00005    Part of the Adonthell Project http://adonthell.linuxgames.com
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License.
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY.
00011 
00012    See the COPYING file for more details
00013 */
00014 
00015 
00016 /**
00017  * @file   dialog_screen.cc
00018  * @author Kai Sterker <kaisterker@linuxgames.com>
00019  *
00020  * @brief  Defines the dialog_screen class.
00021  *
00022  *
00023  */
00024 
00025 
00026 #include <iostream>
00027 
00028 #include "gamedata.h"
00029 #include "input.h"
00030 #include "image.h"
00031 #include "python_class.h"
00032 #include "input.h"
00033 #include "dialog_screen.h"
00034 #include "win_manager.h"
00035 
00036 #include "audio.h"
00037 
00038 // Init the dialogue engine
00039 dialog_screen::dialog_screen (character_base *mynpc, char * dlg_file, u_int8 size)
00040 {
00041     init (mynpc, dlg_file, size);
00042 }
00043 
00044 void dialog_screen::init(character_base *mynpc, char * dlg_file, u_int8 size)
00045 {
00046     string path = dlg_file;
00047     string file = strrchr (dlg_file, '.') ? strrchr (dlg_file, '.') + 1 : dlg_file;
00048 
00049     audio::play_wave (-1, 0);
00050     is_running = true;
00051     portrait = "None";
00052     
00053     // Init position & size
00054     win_container::move (15, 15);
00055     win_container::resize (290, 115);
00056 
00057     // Load the different fonts
00058     fonts[0] = win_manager::get_font ("white");
00059     fonts[1] = win_manager::get_font ("yellow");
00060     fonts[2] = win_manager::get_font ("red");
00061     fonts[3] = win_manager::get_font ("violet");
00062     fonts[4] = win_manager::get_font ("blue");
00063     fonts[5] = win_manager::get_font ("green");
00064 
00065     theme = win_manager::get_theme ("original");
00066 
00067     set_border (*theme);
00068     set_background (*theme);
00069     set_trans_background (true);
00070 
00071     // Full or half-sized window
00072     if (size)
00073     {
00074         move (20, 15);
00075         resize (280, 210);
00076     }
00077 
00078     // Init the low level dialogue stuff
00079     dlg = new dialog (mynpc);
00080 
00081     // Create dialogue window
00082     // The NPC's portrait
00083     face = new win_image();
00084     face->move (5, 5);
00085     ((image*)face)->resize (64, 64);
00086     face->pack();
00087     face->set_visible (true);
00088 
00089     // The NPC's name
00090     name = new win_label ();
00091     name->set_font (*(fonts[0]));
00092     name->move (5, 74);
00093     ((label*)name)->resize (64, 0);
00094     name->set_form (label::AUTO_HEIGHT);
00095     name->set_visible (true);
00096 
00097     // The list with the dialogue
00098     sel = new win_select ();
00099     sel->set_scrollbar (*theme);
00100     sel->move (80, 0);
00101     sel->resize (210, height ());
00102     sel->set_mode (win_select::MODE_BRIGHTNESS);
00103     sel->set_layout (win_container::LIST_LAYOUT);
00104     sel->set_space_with_border (5);
00105     sel->set_space_with_object (5);
00106     sel->set_circle (true);
00107     sel->set_visible_scrollbar (true);
00108     // Commented 'cause it makes troubles during dialogues right now :) 
00109     //     sel->set_auto_scrollbar (true);
00110     sel->set_activate (true);
00111 
00112     sel->set_visible (true);
00113     sel->set_focus (true); //due an error from window system
00114 
00115     // Notification when a dialogue item get's selected
00116     sel->set_signal_connect (makeFunctor (*this,  &dialog_screen::on_select),
00117                              win_event::ACTIVATE_KEY);
00118 
00119     // add everything to our container
00120     add (face);
00121     add (name);
00122     add (sel);
00123     set_focus_object (sel);
00124 
00125     set_visible_border (true);
00126     set_visible_background (true);
00127 
00128     set_visible (true);
00129     set_activate (true);
00130 
00131     // Make the npc and player available to the dialogue engine
00132     PyObject *args = PyTuple_New (2);
00133     PyTuple_SetItem (args, 0, python::pass_instance (data::the_player, "character"));
00134     PyTuple_SetItem (args, 1, python::pass_instance (mynpc, "character_base"));
00135 
00136     // Load dialogue
00137     if (!dlg->init (path, file, args))
00138     {
00139         cout << "\n*** Error loading dialogue script " << file << "\n";
00140 #ifdef PY_DEBUG
00141         python::show_traceback ();
00142 #endif
00143         cout << flush;
00144         answer = -1;    
00145     }
00146     else answer = 0;
00147 
00148     // Clean up
00149     Py_DECREF (args);
00150 }
00151 
00152 dialog_screen::~dialog_screen ()
00153 {
00154     sel->set_activate (false);
00155 
00156     delete dlg;
00157 
00158     // get rid of any keys that might have been accidently pressed during dialogue
00159     input::clear_keys_queue ();
00160 }
00161 
00162 void dialog_screen::run ()
00163 {
00164     u_int32 i = 0;
00165     win_label *l;
00166 
00167     // Possibly error
00168     if (answer < 0)
00169     {
00170         is_running = false;
00171         return;
00172     }
00173 
00174     // Continue dialogue with selected answer
00175     dlg->run (answer);
00176 
00177     // End of dialogue
00178     if (dlg->text_size () == 0)
00179     {
00180         is_running = false;
00181         return;
00182     }
00183 
00184     // update the NPC's portrait and name
00185     set_portrait (dlg->npc_portrait ());
00186     set_name (dlg->npc_name ());
00187 
00188     // Add NPC text and all player reactions to container
00189     for (string txt = dlg->text (); txt != ""; txt = dlg->text (), i++)
00190     {
00191         l = new win_label();
00192         l->set_font (i == 0 ? *fonts[dlg->npc_color ()] : *fonts[1]);
00193         l->move(0,0);
00194         ((label*)l)->resize(190,0);
00195         l->set_form(label::AUTO_HEIGHT);
00196         l->set_text (txt);
00197         l->set_visible (true);
00198         l->pack();
00199         cur_answers.push_back (l);
00200         sel->add (l);
00201     }
00202 
00203     // Either select the single NPC speech ...
00204     if (dlg->text_size () == 1)
00205         sel->set_default_object (cur_answers.front ());
00206 
00207     // ... or the player's first answer
00208     else
00209     {
00210         cur_answers[0]->set_can_be_selected (false);
00211         sel->set_default_object (cur_answers[1]);
00212     }
00213 
00214     // Center on the NPC answer
00215     sel->set_pos (0);
00216 }
00217 
00218 bool dialog_screen::update ()
00219 {
00220     return (win_container::update() && is_running);
00221 }
00222 
00223 void dialog_screen::on_select ()
00224 {
00225     // remember choice
00226     answer = sel->get_selected_position () - 1;
00227 
00228     // remove all the text
00229     sel->destroy ();
00230 
00231     cur_answers.clear ();
00232     
00233     run ();
00234 }
00235 
00236 void dialog_screen::insert_plugin ()
00237 {
00238 }
00239 
00240 // Set / change the NPC-portrait
00241 void dialog_screen::set_portrait (const string & new_portrait)
00242 {
00243     if (new_portrait == portrait) return;
00244     else portrait = new_portrait;
00245 
00246     if (new_portrait == "")
00247     {
00248         face->image::resize (64, 64);
00249         face->fillrect (0, 0, 64, 64, 0x00ff00ff);
00250         return;
00251     }
00252     face->load_pnm(string ("gfx/portraits/") + new_portrait);
00253     face->set_mask(true);
00254     face->pack();
00255 }
00256 
00257 // Set / change the NPC-name
00258 void dialog_screen::set_name (const string & new_name)
00259 {
00260     name->set_text (new_name);
00261     name->pack ();
00262 }
00263 
00264 // Set a different NPC
00265 void dialog_screen::set_npc (const string & new_npc)
00266 {
00267     character_base *mynpc = (character_base *) data::characters[new_npc.c_str ()];
00268     
00269     set_name (mynpc->get_name());
00270     set_portrait (mynpc->get_portrait ());
00271 }

Generated on Fri Mar 18 2011 for Adonthell by  doxygen 1.7.1