Adonthell
0.4
|
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 }