ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/bin/cfplus
(Generate patch)

Comparing deliantra/Deliantra-Client/bin/cfplus (file contents):
Revision 1.29 by root, Mon May 29 21:54:16 2006 UTC vs.
Revision 1.74 by root, Sun Jun 18 17:13:12 2006 UTC

25# need to do it again because that pile of garbage called PAR nukes it before main 25# need to do it again because that pile of garbage called PAR nukes it before main
26unshift @INC, $ENV{PAR_TEMP} 26unshift @INC, $ENV{PAR_TEMP}
27 if %PAR::LibCache; 27 if %PAR::LibCache;
28 28
29use Time::HiRes 'time'; 29use Time::HiRes 'time';
30use Pod::POM;
31use Event; 30use Event;
32 31
33use Crossfire; 32use Crossfire;
34use Crossfire::Protocol::Constants; 33use Crossfire::Protocol::Constants;
35 34
39use CFClient::OpenGL (); 38use CFClient::OpenGL ();
40use CFClient::Protocol; 39use CFClient::Protocol;
41use CFClient::UI; 40use CFClient::UI;
42use CFClient::MapWidget; 41use CFClient::MapWidget;
43 42
43$SIG{QUIT} = sub { Carp::cluck "QUIT" };
44
44$Event::DIED = sub { 45$Event::DIED = sub {
45 # TODO: display dialog box or so 46 # TODO: display dialog box or so
47 Carp::confess $_[1];#d#TODO: remove when stable
46 CFClient::error $_[1]; 48 CFClient::error $_[1];
47}; 49};
48 50
49#$SIG{__WARN__} = sub { Carp::cluck $_[0] };#d# 51#$SIG{__WARN__} = sub { Carp::cluck $_[0] };#d#
50 52
81our $LOGVIEW; 83our $LOGVIEW;
82our $CONSOLE; 84our $CONSOLE;
83our $METASERVER; 85our $METASERVER;
84our $LOGIN_BUTTON; 86our $LOGIN_BUTTON;
85our $QUIT_DIALOG; 87our $QUIT_DIALOG;
86our $SERVER_SETUP; 88our $HOST_ENTRY;
89our $SERVER_INFO;
87 90
91our $SETUP_DIALOG;
92our $SETUP_NOTEBOOK;
93our $SETUP_SERVER;
94our $SETUP_KEYBOARD;
95our $SETUP_SPELLS;
96
97our $STATS_WINDOW;
98our $MESSAGE_WINDOW;
88our $FLOORBOX; 99our $FLOORBOX;
89our $GAUGES; 100our $GAUGES;
90our $STATWIDS; 101our $STATWIDS;
91 102
92our $SDL_ACTIVE; 103our $SDL_ACTIVE;
103our $INV_WINDOW; 114our $INV_WINDOW;
104our $INV; 115our $INV;
105our $INVR; 116our $INVR;
106our $INV_RIGHT_HB; 117our $INV_RIGHT_HB;
107 118
108our $BIND_WINDOW; 119our $BIND_EDITOR;
120
121our $PICKUP_CFG;
109 122
110sub status { 123sub status {
111 $STATUSBOX->add (CFClient::UI::Label::escape $_[0], pri => -10, group => "status", timeout => 10, fg => [1, 1, 0, 1]); 124 $STATUSBOX->add (CFClient::UI::Label::escape $_[0], pri => -10, group => "status", timeout => 10, fg => [1, 1, 0, 1]);
112} 125}
113 126
114sub debug { 127sub debug {
115 $DEBUG_STATUS->set_text ($_[0]); 128 $DEBUG_STATUS->set_text ($_[0]);
116 my ($w, $h) = $DEBUG_STATUS->size_request; 129}
117 $DEBUG_STATUS->move ($WIDTH - $w, 0); 130
131sub destroy_query_dialog {
132 (delete $_[0]{query_dialog})->destroy
133 if $_[0]{query_dialog};
134}
135
136# server query dialog
137sub server_query {
138 my ($conn, $flags, $prompt) = @_;
139
140 $conn->{query_dialog} = my $dialog = new CFClient::UI::FancyFrame
141 x => "center",
142 y => "center",
143 title => "Server Query",
144 child => my $vbox = new CFClient::UI::VBox,
145 ;
146
147 my @dialog = my $label = new CFClient::UI::Label
148 max_w => $::WIDTH * 0.4,
149 ellipsise => 0,
150 text => $prompt;
151
152 if ($flags & CS_QUERY_YESNO) {
153 push @dialog, my $hbox = new CFClient::UI::HBox;
154
155 $hbox->add (new CFClient::UI::Button
156 text => "No",
157 on_activate => sub {
158 $conn->send ("reply n");
159 $dialog->destroy;
160 0
161 }
162 );
163 $hbox->add (new CFClient::UI::Button
164 text => "Yes",
165 on_activate => sub {
166 $conn->send ("reply y");
167 destroy_query_dialog $conn;
168 0
169 },
170 );
171
172 $dialog->grab_focus;
173
174 } elsif ($flags & CS_QUERY_SINGLECHAR) {
175 $dialog->{tooltip} = "Press a key (click on the entry to make sure it has keyboard focus)";
176
177 if ($prompt =~ /Now choose a character|Press any key for the next race/i) {
178 $MESSAGE_WINDOW->show;
179
180 unshift @dialog, new CFClient::UI::Label
181 max_w => $::WIDTH * 0.4,
182 ellipsise => 0,
183 markup => "\nOr use your keyboard:\n";
184
185 unshift @dialog, my $table = new CFClient::UI::Table;
186
187 $table->add (0, 0, new CFClient::UI::Button
188 text => "Next Race",
189 on_activate => sub {
190 $conn->send ("reply n");
191 destroy_query_dialog $conn;
192 0
193 },
194 );
195 $table->add (2, 0, new CFClient::UI::Button
196 text => "Accept",
197 on_activate => sub {
198 $conn->send ("reply d");
199 destroy_query_dialog $conn;
200 0
201 },
202 );
203
204 unshift @dialog, new CFClient::UI::Label
205 max_w => $::WIDTH * 0.4,
206 ellipsise => 0,
207 markup =>
208 "<big><b>Character Creation: Race</b></big>\n\n"
209 . "Look at the <b>Messages</b> window to see a description of this race "
210 . "(<small>or hover with your mouse over the bottommost entry in the status area in the lower left area of the screen</small>) "
211 . "and the center of the screen to see how this race looks like "
212 . "(<small>this is below this dialog window, you may need to click on the display area to make it visible</small>).\n\n"
213 . "You can look at another race, or accept this race (you will come back to this race eventually, "
214 . "so you can take your time making this important choice."
215 ;
216
217 } elsif ($prompt =~ /roll new stats/) {
218 if (my $stat = delete $conn->{stat_change_with}) {
219 $conn->send ("reply $stat");
220 destroy_query_dialog $conn;
221 return;
222 }
223
224 $STATS_WINDOW->show;
225 $MESSAGE_WINDOW->hide;
226
227 unshift @dialog, new CFClient::UI::Label
228 max_w => $::WIDTH * 0.4,
229 ellipsise => 0,
230 markup => "\nOr use your keyboard:\n";
231
232 unshift @dialog, my $table = new CFClient::UI::Table;
233
234 # left: re-roll
235 $table->add (0, 0, new CFClient::UI::Button
236 text => "Roll Again",
237 on_activate => sub {
238 $conn->send ("reply y");
239 destroy_query_dialog $conn;
240 0
241 },
242 );
243
244 # center: swap stats
245 my ($sw1, $sw2) = map +(new CFClient::UI::Combobox
246 value => $_,
247 options => [
248 [1 => "Str", "Strength ($conn->{stat}{+CS_STAT_STR})"],
249 [2 => "Dex", "Dexterity ($conn->{stat}{+CS_STAT_DEX})"],
250 [3 => "Con", "Constitution ($conn->{stat}{+CS_STAT_CON})"],
251 [4 => "Int", "Intelligence ($conn->{stat}{+CS_STAT_INT})"],
252 [5 => "Wis", "Wisdom ($conn->{stat}{+CS_STAT_WIS})"],
253 [6 => "Pow", "Power ($conn->{stat}{+CS_STAT_POW})"],
254 [7 => "Cha", "Charisma ($conn->{stat}{+CS_STAT_CHA})"],
255 ],
256 ), 1 .. 2;
257
258 $table->add (2, 0, new CFClient::UI::Button
259 text => "Swap Stats",
260 on_activate => sub {
261 $conn->{stat_change_with} = $sw2->{value};
262 $conn->send ("reply $sw1->{value}");
263 destroy_query_dialog $conn;
264 0
265 },
266 );
267 $table->add (2, 1, new CFClient::UI::HBox children => [$sw1, $sw2]);
268
269 # right: accept
270 $table->add (4, 0, new CFClient::UI::Button
271 text => "Accept",
272 on_activate => sub {
273 $conn->send ("reply n");
274 $STATS_WINDOW->hide;
275 destroy_query_dialog $conn;
276 0
277 },
278 );
279
280 unshift @dialog, new CFClient::UI::Label
281 max_w => $::WIDTH * 0.4,
282 ellipsise => 0,
283 markup =>
284 "<big><b>Character Creation: Stats</b></big>\n\n"
285 . "Look at the <b>Stats</b> window to see your basic stats "
286 . "(first column: 1 strength, 2 dexterity, 3 constitution, 4 intelligence, 5 wisdom, 6 power and 7 charisma).\n\n"
287 . "You can create another set of stats, swap two stat values with each other or accept the stats as they are now and continue. "
288 . "Race selection will influence those values later on."
289 ;
290 }
291
292 push @dialog, my $entry = new CFClient::UI::Entry
293 on_changed => sub {
294 $conn->send ("reply $_[1]");
295 destroy_query_dialog $conn;
296 0
297 },
298 ;
299
300 $entry->grab_focus;
301
302 } else {
303 $dialog->{tooltip} = "Enter the reply and press return (click on the entry to make sure it has keyboard focus)";
304
305 push @dialog, my $entry = new CFClient::UI::Entry
306 $flags & CS_QUERY_HIDEINPUT ? (hidden => "*") : (),
307 on_activate => sub {
308 $conn->send ("reply $_[1]");
309 destroy_query_dialog $conn;
310 0
311 },
312 ;
313
314 $entry->grab_focus;
315 }
316
317 $vbox->add (@dialog);
318 $dialog->show;
118} 319}
119 320
120sub start_game { 321sub start_game {
121 status "logging in..."; 322 status "logging in...";
122 323
123 $LOGIN_BUTTON->set_text ("Logout"); 324 $LOGIN_BUTTON->set_text ("Logout");
124 $SERVER_SETUP->hide; 325 $SETUP_DIALOG->hide;
125 326
126 my $mapsize = List::Util::min 32, List::Util::max 11, int $WIDTH * $CFG->{mapsize} * 0.01 / 32; 327 my $mapsize = List::Util::min 32, List::Util::max 11, int $WIDTH * $CFG->{mapsize} * 0.01 / 32;
127 328
128 my ($host, $port) = split /:/, $CFG->{host}; 329 my ($host, $port) = split /:/, $CFG->{host};
129 330
141 map_widget => $MAPWIDGET, 342 map_widget => $MAPWIDGET,
142 logview => $LOGVIEW, 343 logview => $LOGVIEW,
143 statusbox => $STATUSBOX, 344 statusbox => $STATUSBOX,
144 map => $MAP, 345 map => $MAP,
145 mapmap => $MAPMAP, 346 mapmap => $MAPMAP,
347 query => \&server_query,
146 348
147 sound_play => sub { 349 sound_play => sub {
148 my ($x, $y, $soundnum, $type) = @_; 350 my ($x, $y, $soundnum, $type) = @_;
149 351
150 $SDL_MIXER 352 $SDL_MIXER
167 } 369 }
168} 370}
169 371
170sub stop_game { 372sub stop_game {
171 $LOGIN_BUTTON->set_text ("Login"); 373 $LOGIN_BUTTON->set_text ("Login");
172 $SERVER_SETUP->show; 374 $SETUP_NOTEBOOK->set_current_page ($SETUP_SERVER);
375 $SETUP_DIALOG->show;
173 $INV_WINDOW->hide; 376 $INV_WINDOW->hide;
174 $LOGVIEW->hide; 377 $SETUP_SPELLS->clear_spells;
175 378
176 return unless $CONN; 379 return unless $CONN;
177 380
178 status "connection closed"; 381 status "connection closed";
179 382
383 destroy_query_dialog $CONN;
180 $CONN->destroy; 384 $CONN->destroy;
181 $CONN = 0; # false, does not autovivify 385 $CONN = 0; # false, does not autovivify
182} 386}
183 387
184sub client_setup { 388sub graphics_setup {
185 my $dialog = new CFClient::UI::FancyFrame
186 req_x => 1,
187 req_y => $HEIGHT * (1/8),
188 name => "client_setup",
189 title => "Client Setup",
190 child => (my $vbox = new CFClient::UI::VBox); 389 my $vbox = new CFClient::UI::VBox;
390
191 $vbox->add (my $table = new CFClient::UI::Table expand => 1, col_expand => [0, 1]); 391 $vbox->add (my $table = new CFClient::UI::Table expand => 1, col_expand => [0, 1]);
192 392
193 $table->add (0, 0, new CFClient::UI::Label valign => 0, align => 1, text => "Video Mode"); 393 $table->add (0, 0, new CFClient::UI::Label valign => 0, align => 1, text => "Video Mode");
194 $table->add (1, 0, my $hbox = new CFClient::UI::HBox); 394 $table->add (1, 0, my $hbox = new CFClient::UI::HBox);
195 395
196 $hbox->add (my $mode_slider = new CFClient::UI::Slider expand => 1, req_w => 100, range => [$CFG->{sdl_mode}, 0, $#SDL_MODES, 0, 1]); 396 $hbox->add (my $mode_slider = new CFClient::UI::Slider force_w => $WIDTH * 0.1, expand => 1, range => [$CFG->{sdl_mode}, 0, $#SDL_MODES, 0, 1]);
197 $hbox->add (my $mode_label = new CFClient::UI::Label align => 0, valign => 0, height => 0.8, template => "9999x9999"); 397 $hbox->add (my $mode_label = new CFClient::UI::Label align => 0, valign => 0, height => 0.8, template => "9999x9999");
198 398
199 $mode_slider->connect (changed => sub { 399 $mode_slider->connect (changed => sub {
200 my ($self, $value) = @_; 400 my ($self, $value) = @_;
201 401
208 408
209 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Fullscreen"); 409 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Fullscreen");
210 $table->add (1, $row++, new CFClient::UI::CheckBox 410 $table->add (1, $row++, new CFClient::UI::CheckBox
211 state => $CFG->{fullscreen}, 411 state => $CFG->{fullscreen},
212 tooltip => "Bring the client into fullscreen mode.", 412 tooltip => "Bring the client into fullscreen mode.",
213 on_changed => sub { 413 on_changed => sub { my ($self, $value) = @_; $CFG->{fullscreen} = $value; 0 }
214 my ($self, $value) = @_;
215 $CFG->{fullscreen} = $value;
216 }
217 ); 414 );
218 415
219 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Fast & Ugly"); 416 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Fast & Ugly");
220 $table->add (1, $row++, new CFClient::UI::CheckBox 417 $table->add (1, $row++, new CFClient::UI::CheckBox
221 state => $CFG->{fast}, 418 state => $CFG->{fast},
222 tooltip => "Lower the visual quality considerably to speed up rendering.", 419 tooltip => "Lower the visual quality considerably to speed up rendering.",
223 on_changed => sub { 420 on_changed => sub { my ($self, $value) = @_; $CFG->{fast} = $value; 0 }
224 my ($self, $value) = @_;
225 $CFG->{fast} = $value;
226 }
227 ); 421 );
228 422
229 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Map Scale"); 423 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Map Scale");
230 $table->add (1, $row++, new CFClient::UI::Slider 424 $table->add (1, $row++, new CFClient::UI::Slider
231 range => [(log $CFG->{map_scale}) / (log 2), -3, 1, 0, 1], 425 range => [(log $CFG->{map_scale}) / (log 2), -3, 1, 0, 1],
232 tooltip => "Enlarge or shrink the displayed map. Changes are instant.", 426 tooltip => "Enlarge or shrink the displayed map. Changes are instant.",
233 on_changed => sub { 427 on_changed => sub { my ($self, $value) = @_; $CFG->{map_scale} = 2 ** $value; 0 }
234 my ($self, $value) = @_;
235 $CFG->{map_scale} = 2 ** $value;
236 }
237 ); 428 );
238 429
239 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Fog of War"); 430 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Fog of War");
240 $table->add (1, $row++, new CFClient::UI::CheckBox 431 $table->add (1, $row++, new CFClient::UI::CheckBox
241 state => $CFG->{fow_enable}, 432 state => $CFG->{fow_enable},
242 tooltip => "<b>Fog-of-War</b> marks areas that cannot be seen by the player. Changes are instant.", 433 tooltip => "<b>Fog-of-War</b> marks areas that cannot be seen by the player. Changes are instant.",
243 on_changed => sub { 434 on_changed => sub { my ($self, $value) = @_; $CFG->{fow_enable} = $value; 0 }
244 my ($self, $value) = @_;
245 $CFG->{fow_enable} = $value;
246 }
247 ); 435 );
248 436
249 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "FoW Intensity"); 437 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "FoW Intensity");
250 $table->add (1, $row++, new CFClient::UI::Slider 438 $table->add (1, $row++, new CFClient::UI::Slider
251 range => [$CFG->{fow_intensity}, 0, 1, 0, 1 / 256], 439 range => [$CFG->{fow_intensity}, 0, 1, 0, 1 / 256],
252 tooltip => "<b>Fog of War Lightness.</b> The higher the intensity, the lighter the Fog-of-War color. Changes are instant.", 440 tooltip => "<b>Fog of War Lightness.</b> The higher the intensity, the lighter the Fog-of-War color. Changes are instant.",
253 on_changed => sub { 441 on_changed => sub { my ($self, $value) = @_; $CFG->{fow_intensity} = $value; 0 }
254 my ($self, $value) = @_;
255 $CFG->{fow_intensity} = $value;
256 }
257 ); 442 );
258 443
259 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "FoW Smooth"); 444 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "FoW Smooth");
260 $table->add (1, $row++, new CFClient::UI::CheckBox 445 $table->add (1, $row++, new CFClient::UI::CheckBox
261 state => $CFG->{fow_smooth}, 446 state => $CFG->{fow_smooth},
262 tooltip => "Smooth the Fog-of-War a bit to make it more realistic. Changes are instant.", 447 tooltip => "Smooth the Fog-of-War a bit to make it more realistic. Changes are instant.",
263 on_changed => sub { 448 on_changed => sub {
264 my ($self, $value) = @_; 449 my ($self, $value) = @_;
265 $CFG->{fow_smooth} = $value; 450 $CFG->{fow_smooth} = $value;
266 status "Fog of War smoothing requires OpenGL 1.2 or higher" if $CFClient::OpenGL::GL_VERSION < 1.2; 451 status "Fog of War smoothing requires OpenGL 1.2 or higher" if $CFClient::OpenGL::GL_VERSION < 1.2;
452 0
267 } 453 }
268 ); 454 );
269 455
270 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "GUI Fontsize"); 456 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "GUI Fontsize");
271 $table->add (1, $row++, new CFClient::UI::Slider 457 $table->add (1, $row++, new CFClient::UI::Slider
272 range => [$CFG->{gui_fontsize}, 0.5, 2, 0, 0.1], 458 range => [$CFG->{gui_fontsize}, 0.5, 2, 0, 0.1],
273 tooltip => "The base font size used by most GUI elements that do not have their own setting.", 459 tooltip => "The base font size used by most GUI elements that do not have their own setting.",
274 on_changed => sub { $CFG->{gui_fontsize} = $_[1] }, 460 on_changed => sub { $CFG->{gui_fontsize} = $_[1]; 0 },
275 ); 461 );
276 462
277 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Message Fontsize"); 463 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Message Fontsize");
278 $table->add (1, $row++, new CFClient::UI::Slider 464 $table->add (1, $row++, new CFClient::UI::Slider
279 range => [$CFG->{log_fontsize}, 0.5, 2, 0, 0.1], 465 range => [$CFG->{log_fontsize}, 0.5, 2, 0, 0.1],
280 tooltip => "The font size used by the <b>message/server log</b> window only. Changes are instant.", 466 tooltip => "The font size used by the <b>message/server log</b> window only. Changes are instant.",
281 on_changed => sub { $LOGVIEW->set_fontsize ($CFG->{log_fontsize} = $_[1]) }, 467 on_changed => sub { $LOGVIEW->set_fontsize ($CFG->{log_fontsize} = $_[1]); 0 },
282 ); 468 );
283 469
284 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Stats Fontsize"); 470 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Stats Fontsize");
285 471
286 $table->add (1, $row++, new CFClient::UI::Slider 472 $table->add (1, $row++, new CFClient::UI::Slider
287 range => [$CFG->{stat_fontsize}, 0.5, 2, 0, 0.1], 473 range => [$CFG->{stat_fontsize}, 0.5, 2, 0, 0.1],
288 tooltip => "The font size used by the <b>statistics window</b> only. Changes are instant.", 474 tooltip => "The font size used by the <b>statistics window</b> only. Changes are instant.",
289 on_changed => sub { 475 on_changed => sub {
290 $CFG->{stat_fontsize} = $_[1]; 476 $CFG->{stat_fontsize} = $_[1];
291 &set_stats_window_fontsize; 477 &set_stats_window_fontsize;
478 0
292 } 479 }
293 ); 480 );
294 481
295 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Gauge fontsize"); 482 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Gauge fontsize");
296 $table->add (1, $row++, new CFClient::UI::Slider 483 $table->add (1, $row++, new CFClient::UI::Slider
297 range => [$CFG->{gauge_fontsize}, 0.5, 2, 0, 0.1], 484 range => [$CFG->{gauge_fontsize}, 0.5, 2, 0, 0.1],
298 tooltip => "Adjusts the fontsize of the gauges at the bottom right. Changes are instant.", 485 tooltip => "Adjusts the fontsize of the gauges at the bottom right. Changes are instant.",
299 on_changed => sub { 486 on_changed => sub {
300 $CFG->{gauge_fontsize} = $_[1]; 487 $CFG->{gauge_fontsize} = $_[1];
301 &set_gauge_window_fontsize; 488 &set_gauge_window_fontsize;
489 0
302 } 490 }
303 ); 491 );
304 492
305 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Gauge size"); 493 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Gauge size");
306 $table->add (1, $row++, new CFClient::UI::Slider 494 $table->add (1, $row++, new CFClient::UI::Slider
307 range => [$CFG->{gauge_size}, 0.2, 0.8], 495 range => [$CFG->{gauge_size}, 0.2, 0.8],
308 tooltip => "Adjust the size of the stats gauges at the bottom right. Changes are instant.", 496 tooltip => "Adjust the size of the stats gauges at the bottom right. Changes are instant.",
309 on_changed => sub { 497 on_changed => sub {
310 $CFG->{gauge_size} = $_[1]; 498 $CFG->{gauge_size} = $_[1];
311 $GAUGES->{win}->set_size ($WIDTH, int $HEIGHT * $CFG->{gauge_size}); 499 $GAUGES->{win}->set_size ($WIDTH, int $HEIGHT * $CFG->{gauge_size});
500 0
312 } 501 }
313 ); 502 );
314 503
315 $table->add (1, $row++, new CFClient::UI::Button 504 $table->add (1, $row++, new CFClient::UI::Button
316 expand => 1, align => 0, text => "Apply", 505 expand => 1, align => 0, text => "Apply",
317 tooltip => "Apply the video settings", 506 tooltip => "Apply the video settings",
318 on_activate => sub { 507 on_activate => sub {
319 video_shutdown (); 508 video_shutdown ();
320 video_init (); 509 video_init ();
510 0
321 } 511 }
322 ); 512 );
513
514 $vbox
515}
516
517sub audio_setup {
518 my $vbox = new CFClient::UI::VBox;
519
520 $vbox->add (my $table = new CFClient::UI::Table expand => 1, col_expand => [0, 1]);
521
522 my $row = 0;
323 523
324 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Audio Enable"); 524 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Audio Enable");
325 $table->add (1, $row++, new CFClient::UI::CheckBox 525 $table->add (1, $row++, new CFClient::UI::CheckBox
326 state => $CFG->{audio_enable}, 526 state => $CFG->{audio_enable},
327 tooltip => "<b>Master Audio Enable.</b> If enabled, sound effects and music will be played. If disabled, no audio will be used and the soundcard will not be opened.", 527 tooltip => "<b>Master Audio Enable.</b> If enabled, sound effects and music will be played. If disabled, no audio will be used and the soundcard will not be opened.",
328 on_changed => sub { 528 on_changed => sub { $CFG->{audio_enable} = $_[1]; 0 }
329 $CFG->{audio_enable} = $_[1];
330 }
331 ); 529 );
332# $table->add (0, 9, new CFClient::UI::Label valign => 0, align => 1, text => "Effects Volume"); 530# $table->add (0, 9, new CFClient::UI::Label valign => 0, align => 1, text => "Effects Volume");
333# $table->add (1, 8, new CFClient::UI::Slider range => [$CFG->{effects_volume}, 0, 128, 1], on_changed => sub { 531# $table->add (1, 8, new CFClient::UI::Slider range => [$CFG->{effects_volume}, 0, 128, 1], on_changed => sub {
334# $CFG->{effects_volume} = $_[1]; 532# $CFG->{effects_volume} = $_[1];
335# }); 533# });
336 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Background Music"); 534 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Background Music");
337 $table->add (1, $row++, my $hbox = new CFClient::UI::HBox); 535 $table->add (1, $row++, my $hbox = new CFClient::UI::HBox);
338 $hbox->add (new CFClient::UI::CheckBox 536 $hbox->add (new CFClient::UI::CheckBox
339 expand => 1, state => $CFG->{bgm_enable}, 537 expand => 1, state => $CFG->{bgm_enable},
340 tooltip => "If enabled, playing of background music is enabled. If disabled, no background music will be played.", 538 tooltip => "If enabled, playing of background music is enabled. If disabled, no background music will be played.",
341 on_changed => sub { 539 on_changed => sub { $CFG->{bgm_enable} = $_[1]; 0 }
342 $CFG->{bgm_enable} = $_[1];
343 }
344 ); 540 );
345 $hbox->add (new CFClient::UI::Slider 541 $hbox->add (new CFClient::UI::Slider
346 expand => 1, range => [$CFG->{bgm_volume}, 0, 1, 0, 1/128], 542 expand => 1, range => [$CFG->{bgm_volume}, 0, 1, 0, 1/128],
347 tooltip => "The volume of the background music. Changes are instant.", 543 tooltip => "The volume of the background music. Changes are instant.",
348 on_changed => sub { 544 on_changed => sub { $CFG->{bgm_volume} = $_[1]; CFClient::MixMusic::volume $_[1] * 128; 0 }
349 $CFG->{bgm_volume} = $_[1];
350 CFClient::MixMusic::volume $_[1] * 128;
351 }
352 ); 545 );
353 546
354 $table->add (1, $row++, new CFClient::UI::Button 547 $table->add (1, $row++, new CFClient::UI::Button
355 expand => 1, align => 0, text => "Apply", 548 expand => 1, align => 0, text => "Apply",
356 tooltip => "Apply the audio settings", 549 tooltip => "Apply the audio settings",
357 on_activate => sub { 550 on_activate => sub {
358 audio_shutdown (); 551 audio_shutdown ();
359 audio_init (); 552 audio_init ();
553 0
360 } 554 }
361 ); 555 );
362 556
363 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Chat Command"); 557 $vbox
364 $table->add (1, $row++, my $saycmd = new CFClient::UI::Entry
365 text => $CFG->{say_command},
366 tooltip => "This is the command that will be used if you write a line in the message window entry or press <b>\"</b> in the map window. "
367 . "Usually you want to enter something like 'say' or 'shout' or 'gsay' here. "
368 . "But you could also set it to <b>tell <i>playername</i></b> to only chat with that user.",
369 on_changed => sub {
370 my ($self, $value) = @_;
371 $CFG->{say_command} = $value;
372 }
373 );
374
375 $dialog
376} 558}
377 559
378sub set_stats_window_fontsize { 560sub set_stats_window_fontsize {
379 for (values %{$STATWIDS}) { 561 for (values %{$STATWIDS}) {
380 $_->set_fontsize ($::CFG->{stat_fontsize}); 562 $_->set_fontsize ($::CFG->{stat_fontsize});
389 571
390sub make_gauge_window { 572sub make_gauge_window {
391 my $gh = int $HEIGHT * $CFG->{gauge_size}; 573 my $gh = int $HEIGHT * $CFG->{gauge_size};
392 574
393 my $win = new CFClient::UI::Frame ( 575 my $win = new CFClient::UI::Frame (
394 req_x => 0, 576 force_x => 0,
395 req_y => -1, 577 force_y => "max",
396 def_w => $WIDTH, 578 force_w => $WIDTH,
397 def_h => $gh, 579 force_h => $gh,
398 ); 580 );
399 581
400 $win->add (my $hbox = new CFClient::UI::HBox 582 $win->add (my $hbox = new CFClient::UI::HBox
401 children => [ 583 children => [
402 (new CFClient::UI::HBox expand => 1), 584 (new CFClient::UI::HBox expand => 1),
438 &set_gauge_window_fontsize; 620 &set_gauge_window_fontsize;
439 621
440 $win 622 $win
441} 623}
442 624
625sub debug_setup {
626 my $table = new CFClient::UI::Table;
443 627
628 $table->add (0, 0, new CFClient::UI::Label text => "Widget Borders");
629 $table->add (1, 0, new CFClient::UI::CheckBox on_changed => sub { $ENV{CFPLUS_DEBUG} ^= 1; 0 });
630 $table->add (0, 1, new CFClient::UI::Label text => "Tooltip Widget Info");
631 $table->add (1, 1, new CFClient::UI::CheckBox on_changed => sub { $ENV{CFPLUS_DEBUG} ^= 2; 0 });
632 $table->add (0, 2, new CFClient::UI::Label text => "Show FPS");
633 $table->add (1, 2, new CFClient::UI::CheckBox on_changed => sub { $ENV{CFPLUS_DEBUG} ^= 4; 0 });
634 $table->add (0, 3, new CFClient::UI::Label text => "Suppress Tooltips");
635 $table->add (1, 3, new CFClient::UI::CheckBox on_changed => sub { $ENV{CFPLUS_DEBUG} ^= 8; 0 });
636
637 my @default_smooth = (0.05, 0.13, 0.05, 0.13, 0.30, 0.13, 0.05, 0.13, 0.05);
638
639 for my $x (0..2) {
640 for my $y (0 .. 2) {
641 $table->add ($x + 3, $y,
642 new CFClient::UI::Entry
643 text => $default_smooth[$x * 3 + $y],
644 on_changed => sub { $MAP->{smooth_matrix}[$x * 3 + $y] = $_[1] if $MAP; 0 },
645 );
646 }
647 }
648
649
650 $table
651}
652
444sub make_stats_window { 653sub stats_window {
445 my $tgw = new CFClient::UI::FancyFrame 654 my $tgw = new CFClient::UI::FancyFrame
446 req_y => $HEIGHT * (2/8), 655 y => $HEIGHT * (2/8),
447 req_x => -1, 656 x => "max",
448 title => "Stats", 657 title => "Stats",
449 name => "stats_window"; 658 name => "stats_window",
659 has_close_button => 1;
450 660
451 $tgw->add (new CFClient::UI::Window child => my $vb = new CFClient::UI::VBox); 661 $tgw->add (new CFClient::UI::Window child => my $vb = new CFClient::UI::VBox);
452 $vb->add ($STATWIDS->{title} = new CFClient::UI::Label valign => 0, align => -1, text => "Title:", expand => 1, 662 $vb->add ($STATWIDS->{title} = new CFClient::UI::Label valign => 0, align => -1, text => "Title:", expand => 1,
453 can_hover => 1, can_events => 1, 663 can_hover => 1, can_events => 1,
454 tooltip => "Your name and title. You can change your title by using the <b>title</b> command, if supported by the server."); 664 tooltip => "Your name and title. You can change your title by using the <b>title</b> command, if supported by the server.");
553 update_stats_window ({}); 763 update_stats_window ({});
554 764
555 $tgw 765 $tgw
556} 766}
557 767
558sub formsep { 768sub formsep($) {
559 reverse join ",", grep length, split /(...)/, reverse $_[0] * 1 769 scalar reverse join ",", unpack "(A3)*", reverse $_[0] * 1
560} 770}
561 771
562sub update_stats_window { 772sub update_stats_window {
563 my ($stats) = @_; 773 my ($stats) = @_;
564 774
600 $STATWIDS->{st_spd} ->set_text (sprintf "%.1f", $stats->{+CS_STAT_SPEED}); 810 $STATWIDS->{st_spd} ->set_text (sprintf "%.1f", $stats->{+CS_STAT_SPEED});
601 $STATWIDS->{st_wspd}->set_text (sprintf "%.1f", $stats->{+CS_STAT_WEAP_SP}); 811 $STATWIDS->{st_wspd}->set_text (sprintf "%.1f", $stats->{+CS_STAT_WEAP_SP});
602 812
603 $STATWIDS->{m_weight}->set_text (sprintf "Max weight: %.1fkg", $stats->{+CS_STAT_WEIGHT_LIM} / 1000); 813 $STATWIDS->{m_weight}->set_text (sprintf "Max weight: %.1fkg", $stats->{+CS_STAT_WEIGHT_LIM} / 1000);
604 814
605 # TODO: replace by CS_STAT_RES_xxx constants
606 my %tbl = ( 815 my %tbl = (
607 phys => 100, 816 phys => CS_STAT_RES_PHYS,
608 magic => 101, 817 magic => CS_STAT_RES_MAG,
609 fire => 102, 818 fire => CS_STAT_RES_FIRE,
610 elec => 103, 819 elec => CS_STAT_RES_ELEC,
611 cold => 104, 820 cold => CS_STAT_RES_COLD,
612 conf => 105, 821 conf => CS_STAT_RES_CONF,
613 acid => 106, 822 acid => CS_STAT_RES_ACID,
614 drain => 107, 823 drain => CS_STAT_RES_DRAIN,
615 ghit => 108, 824 ghit => CS_STAT_RES_GHOSTHIT,
616 pois => 109, 825 pois => CS_STAT_RES_POISON,
617 slow => 110, 826 slow => CS_STAT_RES_SLOW,
618 para => 111, 827 para => CS_STAT_RES_PARA,
619 tund => 112, 828 tund => CS_STAT_TURN_UNDEAD,
620 fear => 113, 829 fear => CS_STAT_RES_FEAR,
621 depl => 113, 830 depl => CS_STAT_RES_DEPLETE,
622 deat => 115, 831 deat => CS_STAT_RES_DEATH,
623 holyw => 116, 832 holyw => CS_STAT_RES_HOLYWORD,
624 blind => 117, 833 blind => CS_STAT_RES_BLIND,
625 ); 834 );
626 835
627 $STATWIDS->{"res_$_"}->set_text (sprintf "%d%", $stats->{$tbl{$_}}) 836 $STATWIDS->{"res_$_"}->set_text (sprintf "%d%", $stats->{$tbl{$_}})
628 for keys %tbl; 837 for keys %tbl;
629} 838}
630 839
631sub metaserver_dialog {
632 my $dialog = new CFClient::UI::FancyFrame
633 title => "Server List",
634 child => (my $vbox = new CFClient::UI::VBox);
635
636 $vbox->add ($dialog->{table} = new CFClient::UI::Table);
637
638 $dialog
639}
640
641my $METASERVER_ATIME; 840my $METASERVER_ATIME;
642 841
643sub update_metaserver { 842sub update_metaserver {
644 my ($HOST) = @_;
645
646 return if $METASERVER_ATIME > time; 843 return if $METASERVER_ATIME > time;
647 $METASERVER_ATIME = time + 60; 844 $METASERVER_ATIME = time + 60;
648 845
649 my $table = $METASERVER->{table}; 846 my $table = $METASERVER->{table};
650 $table->clear; 847 $table->clear;
671 868
672 utf8::decode $buf if utf8::valid $buf; 869 utf8::decode $buf if utf8::valid $buf;
673 870
674 $table->clear; 871 $table->clear;
675 872
873 my @tip = (
874 "The current number of users logged in on the server.",
875 "The hostname of the server.",
876 "The time this server has been running without being restarted.",
877 "The server software version - a '+' indicates a Crossfire+ server.",
878 "Short information about this server provided by its admins.",
879 );
676 my @col = qw(Use #Users Host Uptime Version Description); 880 my @col = qw(#Users Host Uptime Version Description);
677 $table->add ($_, 0, new CFClient::UI::Label align => 0, fg => [1, 1, 0], text => $col[$_]) 881 $table->add ($_, 0, new CFClient::UI::Label
882 can_hover => 1, can_events => 1,
883 align => 0, fg => [1, 1, 0],
884 text => $col[$_], tooltip => $tip[$_])
678 for 0 .. $#col; 885 for 0 .. $#col;
679 886
680 my @align = qw(1 0 1 1 -1); 887 my @align = qw(1 0 1 1 -1);
681 888
682 my $y = 0; 889 my $y = 0;
683 for my $m (sort { $b->[3] <=> $a->[3] } map [split /\|/], split /\015?\012/, $buf) { 890 for my $m (sort { $b->[3] <=> $a->[3] } map [split /\|/], split /\015?\012/, $buf) {
700 907
701 $m = [$users, $host, $uptime, $version, $desc]; 908 $m = [$users, $host, $uptime, $version, $desc];
702 909
703 $y++; 910 $y++;
704 911
705 $table->add (0, $y, new CFClient::UI::VBox children => [ 912 $table->add (scalar @$m, $y, new CFClient::UI::VBox children => [
706 (new CFClient::UI::Button text => "Use", on_activate => sub { 913 (new CFClient::UI::Button
914 text => "Use",
915 tooltip => "Put this server into the <b>Host:Port</b> field",
916 on_activate => sub {
707 $HOST->set_text ($CFG->{host} = $host); 917 $HOST_ENTRY->set_text ($CFG->{host} = $host);
918 $METASERVER->hide;
919 0
920 },
708 }), 921 ),
709 (new CFClient::UI::Empty expand => 1), 922 (new CFClient::UI::Empty expand => 1),
710 ]); 923 ]);
711 924
712 $table->add ($_ + 1, $y, new CFClient::UI::Label 925 $table->add ($_, $y, new CFClient::UI::Label
713 ellipsise => 0, align => $align[$_], text => $m->[$_], fontsize => 0.8) 926 ellipsise => 0,
927 align => $align[$_],
928 text => $m->[$_],
929 tooltip => $tip[$_],
930 can_hover => 1,
931 can_events => 1,
932 fontsize => 0.8)
714 for 0 .. $#$m; 933 for 0 .. $#$m;
715 } 934 }
716 } 935 }
717 }); 936 });
718} 937}
719 938
720sub server_setup { 939sub metaserver_dialog {
721 my $dialog = $SERVER_SETUP = new CFClient::UI::FancyFrame 940 my $dialog = new CFClient::UI::FancyFrame
722 x => $WIDTH * (1/3), 941 title => "Server List",
723 y => $HEIGHT * (1/8), 942 name => 'metaserver_dialog',
724 name => "server_setup", 943 x => 'center',
725 title => "Server Setup", 944 y => 'center',
945 z => 3,
946 force_h => $::HEIGHT * 0.4,
726 child => (my $vbox = new CFClient::UI::VBox), 947 child => (my $vbox = new CFClient::UI::VBox),
727 on_visibility_change => sub { 948 on_visibility_change => sub {
728 my ($self, $visible) = @_; 949 update_metaserver if $_[1];
729 $self->center if $visible; 950 0
730 }, 951 },
731 ; 952 ;
732 953
954 $dialog->{table} = new CFClient::UI::Table;
955
956 $vbox->add (new CFClient::UI::ScrolledWindow expand => 1, child => $dialog->{table});
957
958 $dialog
959}
960
961sub server_setup {
962 my $vbox = new CFClient::UI::VBox;
963
733 $vbox->add (my $table = new CFClient::UI::Table expand => 1, col_expand => [0, 1]); 964 $vbox->add (my $table = new CFClient::UI::Table expand => 1, col_expand => [0, 1]);
734 $table->add (0, 2, new CFClient::UI::Label valign => 0, align => 1, text => "Host:Port"); 965 $table->add (0, 2, new CFClient::UI::Label valign => 0, align => 1, text => "Host:Port");
735 966
736 { 967 {
737 $table->add (1, 2, my $vbox = new CFClient::UI::VBox); 968 $table->add (1, 2, my $vbox = new CFClient::UI::VBox);
738 969
739 $vbox->add ( 970 $vbox->add (
740 my $HOST = new CFClient::UI::Entry 971 $HOST_ENTRY = new CFClient::UI::Entry
741 expand => 1, 972 expand => 1,
742 text => $CFG->{host}, 973 text => $CFG->{host},
743 tooltip => "The hostname or ip address of the Crossfire(+) server to connect to", 974 tooltip => "The hostname or ip address of the Crossfire(+) server to connect to",
744 on_changed => sub { 975 on_changed => sub {
745 my ($self, $value) = @_; 976 my ($self, $value) = @_;
746 $CFG->{host} = $value; 977 $CFG->{host} = $value;
978 0
747 } 979 }
748 ); 980 );
749 981
750 $METASERVER = metaserver_dialog; 982 $METASERVER = metaserver_dialog;
751 983
752 $vbox->add (new CFClient::UI::Flopper 984 $vbox->add (new CFClient::UI::Button
753 expand => 1, 985 expand => 1,
754 text => "Server List", 986 text => "Server List",
755 other => $METASERVER, 987 other => $METASERVER,
756 tooltip => "Show a list of available crossfire servers", 988 tooltip => "Show a list of available crossfire servers",
757 on_open => sub { 989 on_activate => sub { $METASERVER->toggle_visibility; 0 },
758 update_metaserver $HOST; 990 on_visibility_change => sub { $METASERVER->hide unless $_[1]; 0 },
759 }
760 ); 991 );
761 } 992 }
762 993
763 $table->add (0, 4, new CFClient::UI::Label valign => 0, align => 1, text => "Username"); 994 $table->add (0, 4, new CFClient::UI::Label valign => 0, align => 1, text => "Username");
764 $table->add (1, 4, new CFClient::UI::Entry 995 $table->add (1, 4, new CFClient::UI::Entry
765 text => $CFG->{user}, 996 text => $CFG->{user},
766 tooltip => "The name of your character on the server", 997 tooltip => "The name of your character on the server",
767 on_changed => sub { 998 on_changed => sub { my ($self, $value) = @_; $CFG->{user} = $value; 0 }
768 my ($self, $value) = @_;
769 $CFG->{user} = $value;
770 }
771 ); 999 );
772 1000
773 $table->add (0, 5, new CFClient::UI::Label valign => 0, align => 1, text => "Password"); 1001 $table->add (0, 5, new CFClient::UI::Label valign => 0, align => 1, text => "Password");
774 $table->add (1, 5, new CFClient::UI::Entry 1002 $table->add (1, 5, new CFClient::UI::Entry
775 text => $CFG->{password}, 1003 text => $CFG->{password},
776 hidden => 1, 1004 hidden => 1,
777 tooltip => "The password for your character", 1005 tooltip => "The password for your character",
778 on_changed => sub { 1006 on_changed => sub { my ($self, $value) = @_; $CFG->{password} = $value; 0 }
779 my ($self, $value) = @_;
780 $CFG->{password} = $value;
781 }
782 ); 1007 );
783 1008
784 $table->add (0, 7, new CFClient::UI::Label valign => 0, align => 1, text => "Map Size"); 1009 $table->add (0, 7, new CFClient::UI::Label valign => 0, align => 1, text => "Map Size");
785 $table->add (1, 7, new CFClient::UI::Slider 1010 $table->add (1, 7, new CFClient::UI::Slider
786 req_w => 100, 1011 force_w => 100,
787 range => [$CFG->{mapsize}, 10, 100, 0, 1], 1012 range => [$CFG->{mapsize}, 10, 100, 0, 1],
788 tooltip => "This is the size of the portion of the map update the server sends you. " 1013 tooltip => "This is the size of the portion of the map update the server sends you. "
789 . "If you set this to a high value you will be able to see further, " 1014 . "If you set this to a high value you will be able to see further, "
790 . "but you also increase bandwidth requirements and latency. " 1015 . "but you also increase bandwidth requirements and latency. "
791 . "This option is only used once at log-in.", 1016 . "This option is only used once at log-in.",
792 on_changed => sub { 1017 on_changed => sub { my ($self, $value) = @_; $CFG->{mapsize} = $self->{range}[0] = $value = int $value; 0 },
793 my ($self, $value) = @_;
794
795 $CFG->{mapsize} = $self->{range}[0] = $value = int $value;
796 },
797 ); 1018 );
798 1019
799 $table->add (0, 8, new CFClient::UI::Label valign => 0, align => 1, text => "Face Prefetch"); 1020 $table->add (0, 8, new CFClient::UI::Label valign => 0, align => 1, text => "Face Prefetch");
800 $table->add (1, 8, new CFClient::UI::CheckBox 1021 $table->add (1, 8, new CFClient::UI::CheckBox
801 state => $CFG->{face_prefetch}, 1022 state => $CFG->{face_prefetch},
804 . "This might increase or create lag, but increases the chances " 1025 . "This might increase or create lag, but increases the chances "
805 . "of faces being ready for display when you encounter them. " 1026 . "of faces being ready for display when you encounter them. "
806 . "It also uses up server bandwidth on every connect, " 1027 . "It also uses up server bandwidth on every connect, "
807 . "so only set it if you really need to prefetch images. " 1028 . "so only set it if you really need to prefetch images. "
808 . "This option can be set and unset any time.", 1029 . "This option can be set and unset any time.",
809 on_changed => sub { $CFG->{face_prefetch} = $_[1] }, 1030 on_changed => sub { $CFG->{face_prefetch} = $_[1]; 0 },
810 ); 1031 );
811 1032
812 $table->add (0, 9, new CFClient::UI::Label valign => 0, align => 1, text => "Output-Count"); 1033 $table->add (0, 9, new CFClient::UI::Label valign => 0, align => 1, text => "Output-Count");
813 $table->add (1, 9, new CFClient::UI::Entry 1034 $table->add (1, 9, new CFClient::UI::Entry
814 text => $CFG->{output_count}, 1035 text => $CFG->{output_count},
815 tooltip => "Should be set to 1 unless you know what you are doing. This option is only used once at log-in.", 1036 tooltip => "Should be set to 1 unless you know what you are doing. This option is only used once at log-in.",
816 on_changed => sub { $CFG->{output_count} = $_[1] }, 1037 on_changed => sub { $CFG->{output_count} = $_[1]; 0 },
817 ); 1038 );
818 1039
819 $table->add (0, 10, new CFClient::UI::Label valign => 0, align => 1, text => "Output-Sync"); 1040 $table->add (0, 10, new CFClient::UI::Label valign => 0, align => 1, text => "Output-Sync");
820 $table->add (1, 10, new CFClient::UI::Entry 1041 $table->add (1, 10, new CFClient::UI::Entry
821 text => $CFG->{output_sync}, 1042 text => $CFG->{output_sync},
822 tooltip => "Should be set to 1 unless you know what you are doing. This option is only used once at log-in.", 1043 tooltip => "Should be set to 1 unless you know what you are doing. This option is only used once at log-in.",
823 on_changed => sub { $CFG->{output_sync} = $_[1] }, 1044 on_changed => sub { $CFG->{output_sync} = $_[1]; 0 },
824 ); 1045 );
825 1046
826 $table->add (1, 11, $LOGIN_BUTTON = new CFClient::UI::Button 1047 $table->add (1, 11, $LOGIN_BUTTON = new CFClient::UI::Button
827 expand => 1, 1048 expand => 1,
828 align => 0, 1049 align => 0,
829 text => "Login", 1050 text => "Login",
830 on_activate => sub { 1051 on_activate => sub {
831 $CONN ? stop_game 1052 $CONN ? stop_game
832 : start_game; 1053 : start_game;
1054 0
833 }, 1055 },
834 ); 1056 );
835 1057
836 $dialog 1058 $table->add (0, 12, new CFClient::UI::Label valign => 0, align => 1, text => "Chat Command");
1059 $table->add (1, 12, my $saycmd = new CFClient::UI::Entry
1060 text => $CFG->{say_command},
1061 tooltip => "This is the command that will be used if you write a line in the message window entry or press <b>\"</b> in the map window. "
1062 . "Usually you want to enter something like 'say' or 'shout' or 'gsay' here. "
1063 . "But you could also set it to <b>tell <i>playername</i></b> to only chat with that user.",
1064 on_changed => sub {
1065 my ($self, $value) = @_;
1066 $CFG->{say_command} = $value;
1067 0
1068 }
1069 );
1070
1071 $vbox->add (new CFClient::UI::Label
1072 text => "Server Info",
1073 fontsize => 1.2,
1074 padding_y => 8,
1075 fg => [1, 1, 0, 1],
1076 );
1077
1078 $vbox->add ($SERVER_INFO = new CFClient::UI::Label ellipsise => 0);
1079
1080 $vbox
837} 1081}
838 1082
839sub message_window { 1083sub message_window {
840 my $window = new CFClient::UI::FancyFrame 1084 my $window = new CFClient::UI::FancyFrame
841 name => "message_window", 1085 name => "message_window",
842 title => "Messages", 1086 title => "Messages",
843 border_bg => [1, 1, 1, 1], 1087 border_bg => [1, 1, 1, 1],
844 bg => [0, 0, 0, 0.75], 1088 bg => [0, 0, 0, 0.75],
845 req_x => -1, 1089 x => "max",
846 req_y => 0, 1090 y => 0,
847 def_w => int $::WIDTH / 3, 1091 force_w => $::WIDTH * 0.4,
848 def_h => int $::HEIGHT / 5, 1092 force_h => $::HEIGHT * 0.5,
849 child => (my $vbox = new CFClient::UI::VBox); 1093 child => (my $vbox = new CFClient::UI::VBox),
1094 has_close_button => 1;
850 1095
851 $vbox->add ($LOGVIEW); 1096 $vbox->add ($LOGVIEW);
852 1097
853 $vbox->add (my $input = new CFClient::UI::Entry 1098 $vbox->add (my $input = new CFClient::UI::Entry
854 tooltip => "<b>Chat Box</b>. If you enter a text and press return/enter here, the current <i>communication command</i> " 1099 tooltip => "<b>Chat Box</b>. If you enter a text and press return/enter here, the current <i>communication command</i> "
862 1107
863 if ($prev_focus == $MAPWIDGET && $input->{auto_activated}) { 1108 if ($prev_focus == $MAPWIDGET && $input->{auto_activated}) {
864 $input->{refocus_map} = 1; 1109 $input->{refocus_map} = 1;
865 } 1110 }
866 delete $input->{auto_activated}; 1111 delete $input->{auto_activated};
1112
1113 0
867 }, 1114 },
868 on_activate => sub { 1115 on_activate => sub {
869 my ($input, $text) = @_; 1116 my ($input, $text) = @_;
870 $input->set_text (''); 1117 $input->set_text ('');
871 1118
872 if ($text =~ /^\/bind\s+(.*)$/) {
873 CFClient::Recorder::open_binding_dialog ([$1]);
874 } elsif ($text =~ /^\/(.*)/) { 1119 if ($text =~ /^\/(.*)/) {
875 $::CONN->user_send ($1); 1120 $::CONN->user_send ($1);
876 } else { 1121 } else {
877 my $say_cmd = $::CFG->{say_command} || 'say'; 1122 my $say_cmd = $::CFG->{say_command} || 'say';
878 $::CONN->user_send ("$say_cmd $text"); 1123 $::CONN->user_send ("$say_cmd $text");
879 } 1124 }
880 if ($input->{refocus_map}) { 1125 if ($input->{refocus_map}) {
881 delete $input->{refocus_map}; 1126 delete $input->{refocus_map};
882 $MAPWIDGET->focus_in 1127 $MAPWIDGET->focus_in
883 } 1128 }
1129
1130 0
884 }, 1131 },
885 on_escape => sub { 1132 on_escape => sub {
886 $MAPWIDGET->focus_in 1133 $MAPWIDGET->grab_focus;
1134
1135 0
887 }, 1136 },
888 ); 1137 );
889 1138
890 $CONSOLE = { 1139 $CONSOLE = {
891 window => $window, 1140 window => $window,
892 input => $input 1141 input => $input,
893 }; 1142 };
894 1143
895 $window 1144 $window
896} 1145}
897 1146
898sub open_quit_dialog { 1147sub open_quit_dialog {
899 unless ($QUIT_DIALOG) { 1148 unless ($QUIT_DIALOG) {
900 $QUIT_DIALOG = new CFClient::UI::FancyFrame title => "Really Quit?"; 1149 $QUIT_DIALOG = new CFClient::UI::FancyFrame
1150 x => "center",
1151 y => "center",
1152 z => 50,
1153 title => "Really Quit?",
1154 ;
901 1155
902 $QUIT_DIALOG->add (my $vb = new CFClient::UI::VBox expand => 1); 1156 $QUIT_DIALOG->add (my $vb = new CFClient::UI::VBox expand => 1);
903 1157
904 $vb->add (new CFClient::UI::Label 1158 $vb->add (new CFClient::UI::Label
905 text => "You should find a savebed and apply it first!", 1159 text => "You should find a savebed and apply it first!",
908 ); 1162 );
909 $vb->add (my $hb = new CFClient::UI::HBox expand => 1); 1163 $vb->add (my $hb = new CFClient::UI::HBox expand => 1);
910 $hb->add (new CFClient::UI::Button 1164 $hb->add (new CFClient::UI::Button
911 text => "Ok", 1165 text => "Ok",
912 expand => 1, 1166 expand => 1,
913 on_activate => sub { $QUIT_DIALOG->hide }, 1167 on_activate => sub { $QUIT_DIALOG->hide; 0 },
914 ); 1168 );
915 $hb->add (new CFClient::UI::Button 1169 $hb->add (new CFClient::UI::Button
916 text => "Quit anyway", 1170 text => "Quit anyway",
917 expand => 1, 1171 expand => 1,
918 on_activate => sub { exit }, 1172 on_activate => sub { exit },
919 ); 1173 );
920 } 1174 }
921 1175
922 $QUIT_DIALOG->show; 1176 $QUIT_DIALOG->show;
923 $QUIT_DIALOG->center;
924} 1177}
925 1178
1179sub autopickup_setup {
1180 my $table = new CFClient::UI::Table;
1181
1182 for (
1183 ["General", 0, 0,
1184 ["Enable autopickup" => PICKUP_NEWMODE],
1185 ["Inhibit autopickup" => PICKUP_INHIBIT],
1186 ["Stop before pickup" => PICKUP_STOP],
1187 ["Debug autopickup" => PICKUP_DEBUG],
1188 ],
1189 ["Weapons", 0, 6,
1190 ["All weapons" => PICKUP_ALLWEAPON],
1191 ["Missile weapons" => PICKUP_MISSILEWEAPON],
1192 ["Bows" => PICKUP_BOW],
1193 ["Arrows" => PICKUP_ARROW],
1194 ],
1195 ["Armour", 0, 12,
1196 ["Helmets" => PICKUP_HELMET],
1197 ["Shields" => PICKUP_SHIELD],
1198 ["Body Armour" => PICKUP_ARMOUR],
1199 ["Boots" => PICKUP_BOOTS],
1200 ["Gloves" => PICKUP_GLOVES],
1201 ["Cloaks" => PICKUP_CLOAK],
1202 ],
1203
1204 ["Readables", 2, 2,
1205 ["Spellbooks" => PICKUP_SPELLBOOK],
1206 ["Skillscrolls" => PICKUP_SKILLSCROLL],
1207 ["Normal Books/Scrolls" => PICKUP_READABLES],
1208 ],
1209 ["Misc", 2, 7,
1210 ["Food" => PICKUP_FOOD],
1211 ["Drinks" => PICKUP_DRINK],
1212 ["Valuables (Money, Gems)" => PICKUP_VALUABLES],
1213 ["Keys" => PICKUP_KEY],
1214 ["Magical Items" => PICKUP_MAGICAL],
1215 ["Potions" => PICKUP_POTION],
1216 ["Magic Devices" => PICKUP_MAGIC_DEVICE],
1217 ["Ignore cursed" => PICKUP_NOT_CURSED],
1218 ["Jewelery" => PICKUP_JEWELS],
1219 ],
1220 ["Weight/Value ratio", 2, 17]
1221 )
1222 {
1223 my ($title, $x, $y, @bits) = @$_;
1224 $table->add ($x, $y, new CFClient::UI::Label text => $title, align => 1, fg => [1, 1, 0]);
1225
1226 for (@bits) {
1227 ++$y;
1228
1229 my $mask = $_->[1];
1230 $table->add ($x , $y, new CFClient::UI::Label text => $_->[0], align => 1, expand => 1);
1231 $table->add ($x+1, $y, new CFClient::UI::CheckBox
1232 state => $CFG->{pickup} & $mask,
1233 on_changed => sub {
1234 my ($box, $value) = @_;
1235
1236 if ($value) {
1237 $::CFG->{pickup} |= $mask;
1238 } else {
1239 $::CFG->{pickup} &= ~$mask;
1240 }
1241
1242 $::CONN->send_command ("pickup $::CFG->{pickup}")
1243 if defined $::CONN;
1244
1245 0
1246 });
1247 }
1248 }
1249
1250 $table->add (2, 18, new CFClient::UI::ValSlider
1251 range => [0, 0, 16, 1, 1],
1252 to_value => sub { ">= " . 5 * $_[0] },
1253 on_changed => sub {
1254 my ($slider, $value) = @_;
1255
1256 $::CFG->{pickup} &= ~0x7;
1257 $::CFG->{pickup} |= int $value
1258 if $value;
1259 1;
1260 });
1261 $table->add (3, 18, new CFClient::UI::Button
1262 text => "set",
1263 on_activate => sub {
1264 $::CONN->send_command ("pickup $::CFG->{pickup}")
1265 if defined $::CONN;
1266 0
1267 });
1268
1269 $table
1270}
1271
926sub make_inventory_window { 1272sub inventory_window {
927 my $invwin = $INV_WINDOW = new CFClient::UI::FancyFrame 1273 my $invwin = $INV_WINDOW = new CFClient::UI::FancyFrame
1274 x => "center",
1275 y => "center",
928 def_w => $WIDTH * 7/8, 1276 force_w => $WIDTH * 9/10,
929 def_h => $HEIGHT * 7/8, 1277 force_h => $HEIGHT * 9/10,
930 title => "Inventory", 1278 title => "Inventory",
931 name => "inventory_window", 1279 has_close_button => 1,
932 on_visibility_change => sub {
933 my ($self, $visible) = @_;
934 $self->center if $visible;
935 },
936 ; 1280 ;
937 1281
938 $invwin->add (my $hb = new CFClient::UI::HBox homogeneous => 1); 1282 $invwin->add (my $hb = new CFClient::UI::HBox homogeneous => 1);
939 1283
940 $hb->add (my $vb1 = new CFClient::UI::VBox); 1284 $hb->add (my $vb1 = new CFClient::UI::VBox);
951 CFClient::Protocol::set_opencont ($::CONN, 0, "Floor"); 1295 CFClient::Protocol::set_opencont ($::CONN, 0, "Floor");
952 1296
953 $invwin 1297 $invwin
954} 1298}
955 1299
956sub make_binding_window { 1300sub spell_setup {
1301 new CFClient::UI::SpellList
1302}
1303
1304sub keyboard_setup {
957 my $binding_list = new CFClient::UI::VBox; 1305 my $binding_list = new CFClient::UI::VBox;
958 1306
1307 my $refresh;
959 my $refresh = sub { 1308 $refresh = sub {
960 $binding_list->clear (); 1309 $binding_list->clear ();
961 1310
962 for my $mod (keys %{$::CFG->{bindings}}) { 1311 for my $mod (keys %{$::CFG->{bindings}}) {
963 for my $sym (keys %{$::CFG->{bindings}->{$mod}}) { 1312 for my $sym (keys %{$::CFG->{bindings}->{$mod}}) {
964 my $cmds = $::CFG->{bindings}->{$mod}->{$sym}; 1313 my $cmds = $::CFG->{bindings}->{$mod}->{$sym};
965 next unless ref $cmds eq 'ARRAY' and @$cmds > 0; 1314 next unless ref $cmds eq 'ARRAY' and @$cmds > 0;
966 1315
967 my $lbl = join "; ", @$cmds; 1316 my $lbl = join "; ", @$cmds;
968 my $nam = CFClient::Recorder::keycombo_to_name ($mod, $sym); 1317 my $nam = CFClient::Binder::keycombo_to_name ($mod, $sym);
969 $binding_list->add (my $hb = new CFClient::UI::HBox); 1318 $binding_list->add (my $hb = new CFClient::UI::HBox);
970 $hb->add (new CFClient::UI::Button 1319 $hb->add (new CFClient::UI::Button
971 text => "delete", 1320 text => "delete",
1321 tooltip => "Deletes the binding",
972 on_activate => sub { 1322 on_activate => sub {
973 $binding_list->remove ($hb); 1323 $binding_list->remove ($hb);
974 delete $::CFG->{bindings}->{$mod}->{$sym}; 1324 delete $::CFG->{bindings}->{$mod}->{$sym};
1325 0
975 }); 1326 });
1327
1328 $hb->add (new CFClient::UI::Button
1329 text => "edit",
1330 tooltip => "Edits the binding",
1331 on_activate => sub {
1332 $::BIND_EDITOR->set_binding (
1333 $mod, $sym, $::CFG->{bindings}->{$mod}->{$sym},
1334 sub {
1335 my ($nmod, $nsym, $ncmds) = @_;
1336 delete $::CFG->{bindings}->{$mod}->{$sym};
1337 $::CFG->{bindings}->{$nmod}->{$nsym} = $ncmds;
1338 $refresh->();
1339 $SETUP_NOTEBOOK->set_current_page ($SETUP_KEYBOARD);
1340 $SETUP_DIALOG->show;
1341 },
1342 sub {
1343 $SETUP_NOTEBOOK->set_current_page ($SETUP_KEYBOARD);
1344 $SETUP_DIALOG->show;
1345 });
1346 $::BIND_EDITOR->show;
1347 $SETUP_DIALOG->hide;
1348 0
1349 });
1350
976 $hb->add (new CFClient::UI::Label text => "($nam)"); 1351 $hb->add (new CFClient::UI::Label text => "(Key: $nam)");
977 $hb->add (new CFClient::UI::Label text => $lbl, expand => 1); 1352 $hb->add (new CFClient::UI::Label text => $lbl, expand => 1);
978 } 1353 }
979 } 1354 }
980 }; 1355 };
981 1356
1357 my $vb = new CFClient::UI::VBox;
1358 $vb->add (my $hb = new CFClient::UI::HBox);
1359 $hb->add (new CFClient::UI::Label text => "only shift-up stops fire");
1360 $hb->add (new CFClient::UI::CheckBox
1361 expand => 1,
1362 state => $CFG->{shift_fire_stop},
1363 tooltip => "If this checkbox is enabled you will stop fire only if you stop pressing shift",
1364 on_changed => sub {
1365 my ($cbox, $value) = @_;
1366 $CFG->{shift_fire_stop} = $value;
1367 0
1368 });
1369
1370 $vb->add ($binding_list);
1371 $vb->add (my $hb = new CFClient::UI::HBox);
1372
1373 $hb->add (new CFClient::UI::Button
1374 text => "record new",
1375 expand => 1,
1376 tooltip => "This button opens the binding editor with an empty binding.",
1377 on_activate => sub {
1378 $::BIND_EDITOR->set_binding (undef, undef, [],
1379 sub {
1380 my ($mod, $sym, $cmds) = @_;
1381 $::CFG->{bindings}->{$mod}->{$sym} = $cmds;
1382 $refresh->();
1383 $SETUP_NOTEBOOK->set_current_page ($SETUP_KEYBOARD);
1384 $SETUP_DIALOG->show;
1385 },
1386 sub {
1387 $SETUP_NOTEBOOK->set_current_page ($SETUP_KEYBOARD);
1388 $SETUP_DIALOG->show;
1389 },
1390 );
1391 $SETUP_DIALOG->hide;
1392 $::BIND_EDITOR->show;
1393 0
1394 },
1395 );
1396
1397 $hb->add (new CFClient::UI::Button
1398 text => "close",
1399 tooltip => "Closes the binding window",
1400 expand => 1,
1401 on_activate => sub {
1402 $SETUP_DIALOG->hide;
1403 0
1404 }
1405 );
1406
1407 $refresh->();
1408
1409 $vb
1410}
1411
1412sub help_window {
982 $BIND_WINDOW = new CFClient::UI::FancyFrame 1413 my $win = new CFClient::UI::FancyFrame
983 title => "Bindings", 1414 x => 'center',
1415 y => 'center',
1416 z => 2,
1417 name => 'doc_browser',
984 def_w => int $WIDTH * 7/8, 1418 force_w => int $WIDTH * 7/8,
985 def_h => int $HEIGHT * 7/8, 1419 force_h => int $HEIGHT * 7/8,
1420 title => "Documentation";
1421
1422 $win->add (my $vbox = new CFClient::UI::VBox);
1423
1424 $vbox->add (my $buttons = new CFClient::UI::HBox);
1425 $vbox->add (my $viewer = new CFClient::UI::TextScroller
1426 expand => 1, fontsize => 0.8, padding_x => 4);
1427
1428 $buttons->add (new CFClient::UI::Label text => "Choose a document to display: ");
1429 $buttons->add (my $combo = new CFClient::UI::Combobox
1430 value => undef,
1431 options => [
1432 [intro => "Introduction"],
1433 [manual => "Manual"],
1434 [skill_help => "Skills"],
1435 [command_help => "Commands"],
1436 [dmcommand_help => "DM Commands"],
1437 [COPYING => "License Terms"],
1438 ],
1439 on_changed => sub {
1440 my ($self, $pod) = @_;
1441
1442 my $pom = CFClient::load_pod CFClient::find_rcfile "pod/$pod.pod",
1443 doc_viewer => 1, sub { CFClient::pod_to_pango_list $_[0] };
1444
1445 $viewer->clear;
1446
1447 $viewer->add_paragraph ([1, 1, 1, 1], $_->[1], $_->[0])
1448 for @$pom;
1449
1450 $viewer->set_offset (0);
1451 0
1452 },
986 on_visibility_change => sub { 1453 on_visibility_change => sub {
987 my ($self, $visible) = @_; 1454 my ($self, $visible) = @_;
988 if ($visible) { 1455 return unless $visible;
989 $self->center; 1456 return if $self->{value};
990 $refresh->() 1457 $self->set_value ("intro");
991 } 1458 0
992 }; 1459 },
993
994 $BIND_WINDOW->add ($binding_list);
995 $refresh->();
996 $BIND_WINDOW
997}
998
999sub make_help_window {
1000 my $win = new CFClient::UI::FancyFrame
1001 def_w => int $WIDTH * 7/8,
1002 def_h => int $HEIGHT * 7/8,
1003 title => "Documentation";
1004
1005 $win->add (my $vbox = new CFClient::UI::VBox);
1006
1007 $vbox->add (my $buttons = new CFClient::UI::HBox);
1008 $vbox->add (my $viewer = new CFClient::UI::TextView expand => 1, fontsize => 0.8);
1009
1010 for (
1011 [intro => "Introduction"],
1012 [manual => "Manual"],
1013 [command_help => "Commands"],
1014 [skill_help => "Skills"],
1015 ) {
1016 my ($pod, $label) = @$_;
1017
1018 $buttons->add (new CFClient::UI::Button
1019 text => $label,
1020 on_activate => sub {
1021 my $parser = new Pod::POM;
1022 my $pom = $parser->parse_file (CFClient::find_rcfile "pod/$pod.pod");
1023
1024 $viewer->clear;
1025
1026 $viewer->add_paragraph ([1, 1, 1, 1], $_->[1], $_->[0])
1027 for @{ CFClient::pod_to_pango_list $pom };
1028
1029 $viewer->set_offset (0);
1030 },
1031 ); 1460 );
1032 }
1033
1034 $viewer->add_paragraph ([1, 1, 0, 1], "<big>Use one of the buttons above to display a document.</big>");
1035 1461
1036 $win 1462 $win
1037} 1463}
1038 1464
1039sub sdl_init { 1465sub sdl_init {
1069 if ($DEBUG_STATUS) { 1495 if ($DEBUG_STATUS) {
1070 CFClient::UI::rescale_widgets $WIDTH / $old_w, $HEIGHT / $old_h; 1496 CFClient::UI::rescale_widgets $WIDTH / $old_w, $HEIGHT / $old_h;
1071 } else { 1497 } else {
1072 # create the widgets 1498 # create the widgets
1073 1499
1074 $DEBUG_STATUS = new CFClient::UI::Label padding => 0, z => 100, req_x => -1; 1500 $DEBUG_STATUS = new CFClient::UI::Label
1501 padding => 0,
1502 z => 100,
1503 force_x => "max",
1504 force_y => 0;
1075 $DEBUG_STATUS->show; 1505 $DEBUG_STATUS->show;
1076 1506
1507 $BIND_EDITOR = new CFClient::UI::BindEditor (x => "max", y => 0);
1508
1077 $STATUSBOX = new CFClient::UI::Statusbox; 1509 $STATUSBOX = new CFClient::UI::Statusbox;
1078 $STATUSBOX->add ("Use <b>Alt-Enter</b> to toggle fullscreen mode", pri => -100, color => [1, 1, 1, 0.8]); 1510 $STATUSBOX->add ("Use <b>Alt-Enter</b> to toggle fullscreen mode", timeout => 864000, pri => -100, color => [1, 1, 1, 0.8]);
1079 1511
1080 (new CFClient::UI::Frame 1512 (new CFClient::UI::Frame
1081 bg => [0, 0, 0, 0.4], 1513 bg => [0, 0, 0, 0.4],
1082 req_y => -1, 1514 force_x => 0,
1515 force_y => "max",
1083 child => $STATUSBOX, 1516 child => $STATUSBOX,
1084 )->show; 1517 )->show;
1085 1518
1086 CFClient::UI::FancyFrame->new ( 1519 CFClient::UI::FancyFrame->new (
1520 title => "Map",
1521 name => "mapmap",
1522 x => 0,
1523 y => $FONTSIZE + 8,
1087 border_bg => [1, 1, 1, 192/255], 1524 border_bg => [1, 1, 1, 192/255],
1088 bg => [1, 1, 1, 0], 1525 bg => [1, 1, 1, 0],
1089 child => ($MAPMAP = new CFClient::MapWidget::MapMap 1526 child => ($MAPMAP = new CFClient::MapWidget::MapMap
1090 tooltip => "<b>Map</b>. On servers that support this feature, this will display an overview of the surrounding areas.", 1527 tooltip => "<b>Map</b>. On servers that support this feature, this will display an overview of the surrounding areas.",
1091 ), 1528 ),
1095 $MAPWIDGET->connect (activate_console => sub { 1532 $MAPWIDGET->connect (activate_console => sub {
1096 my ($mapwidget, $preset) = @_; 1533 my ($mapwidget, $preset) = @_;
1097 1534
1098 if ($CONSOLE) { 1535 if ($CONSOLE) {
1099 $CONSOLE->{input}->{auto_activated} = 1; 1536 $CONSOLE->{input}->{auto_activated} = 1;
1100 $CONSOLE->{input}->focus_in; 1537 $CONSOLE->{input}->grab_focus;
1101 1538
1102 if ($preset && $CONSOLE->{input}->get_text eq '') { 1539 if ($preset && $CONSOLE->{input}->get_text eq '') {
1103 $CONSOLE->{input}->set_text ($preset); 1540 $CONSOLE->{input}->set_text ($preset);
1104 } 1541 }
1105 } 1542 }
1106 }); 1543 });
1107 $MAPWIDGET->show; 1544 $MAPWIDGET->show;
1108 $MAPWIDGET->focus_in; 1545 $MAPWIDGET->grab_focus;
1109 1546
1110 $LOGVIEW = new CFClient::UI::TextView 1547 $LOGVIEW = new CFClient::UI::TextScroller
1111 expand => 1, 1548 expand => 1,
1112 font => $FONT_FIXED, 1549 font => $FONT_FIXED,
1113 fontsize => $::CFG->{log_fontsize}, 1550 fontsize => $::CFG->{log_fontsize},
1551 indent => -4,
1114 can_hover => 1, 1552 can_hover => 1,
1115 can_events => 1, 1553 can_events => 1,
1116 tooltip => "<b>Server Log</b>. This text viewer contains all the messages sent by the server.", 1554 tooltip => "<b>Server Log</b>. This text viewer contains all the messages sent by the server.",
1117 ; 1555 ;
1118 1556
1119 $BUTTONBAR = new CFClient::UI::HBox; 1557 $SETUP_DIALOG = new CFClient::UI::FancyFrame
1558 title => "Setup",
1559 name => "setup_dialog",
1560 x => 'center',
1561 y => 'center',
1562 z => 2,
1563 force_w => $::WIDTH * 0.6,
1564 force_h => $::HEIGHT * 0.6,
1565 has_close_button => 1,
1566 ;
1120 1567
1568 $SETUP_DIALOG->add ($SETUP_NOTEBOOK = new CFClient::UI::Notebook expand => 1, debug => 1,
1569 filter => new CFClient::UI::ScrolledWindow expand => 1, scroll_y => 1);
1570
1571 $SETUP_NOTEBOOK->add (Server => $SETUP_SERVER = server_setup,
1572 "Configure the server to play on, your username, password and other server-related options.");
1573 $SETUP_NOTEBOOK->add (Pickup => autopickup_setup,
1574 "Configure autopickup settings, i.e. which items you will pick up automatically when walking (or running) over them.");
1575 $SETUP_NOTEBOOK->add (Graphics => graphics_setup,
1576 "Configure the video mode, performance, fonts and other graphical aspects of the game.");
1577 $SETUP_NOTEBOOK->add (Audio => audio_setup,
1578 "Configure the use of audio, sound effects and background music.");
1579 $SETUP_NOTEBOOK->add (Keyboard => $SETUP_KEYBOARD = keyboard_setup,
1580 "Lets you define, edit and delete bindings."
1581 . "There is a shortcut for making bindings: <b>Left Control + Insert</b> opens the binding editor "
1582 . "with nothing set and the recording started. After doing the actions you "
1583 . "want to record press <b>Insert</b> and you will be asked to press a key-combo. "
1584 . "After pressing the combo the binding will be saved automatically and the "
1585 . "binding editor closes");
1586 $SETUP_NOTEBOOK->add (Spells => $SETUP_SPELLS = spell_setup,
1587 "Displays all spells you have and lets you edit keyboard shortcuts for them.");
1588 $SETUP_NOTEBOOK->add (Debug => debug_setup,
1589 "Some debuggign options. Do not ask.");
1590
1591 $BUTTONBAR = new CFClient::UI::Buttonbar x => 0, y => 0, z => 200; # put on top
1592
1121 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Client Setup", other => client_setup, 1593 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Setup", other => $SETUP_DIALOG,
1122 tooltip => "Toggles a dialog where you can configure various aspects of the client, such as graphics mode, performance, and audio options."); 1594 tooltip => "Toggles a dialog where you can configure all aspects of this client.");
1123 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Server Setup", other => server_setup, 1595
1124 tooltip => "Toggles a dialog where you can configure the server to play on, your username, password and other server-related options.");
1125 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Message Window", other => message_window, 1596 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Message Window", other => $MESSAGE_WINDOW = message_window,
1126 tooltip => "Toggles the server message log, where the client collects <i>all</i> messages from the server."); 1597 tooltip => "Toggles the server message log, where the client collects <i>all</i> messages from the server.");
1127 1598
1128 make_gauge_window->show; # XXX: this has to be set before make_stats_window as make_stats_window calls update_stats_window which updated the gauges also X-D 1599 make_gauge_window->show; # XXX: this has to be set before make_stats_window as make_stats_window calls update_stats_window which updated the gauges also X-D
1129 1600
1130 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Stats Window", other => make_stats_window, 1601 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Stats Window", other => $STATS_WINDOW = stats_window,
1131 tooltip => "Toggles the statistics window, where all your Stats and Resistances are being displayed at all times."); 1602 tooltip => "Toggles the statistics window, where all your Stats and Resistances are being displayed at all times.");
1132 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Inventory", other => make_inventory_window, 1603 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Inventory", other => inventory_window,
1133 tooltip => "Toggles the inventory window, where you can manage your loot (or treaures :)."); 1604 tooltip => "Toggles the inventory window, where you can manage your loot (or treasures :). "
1605 . "You can also hit the <b>Tab</b>-key to show/hide the Inventory.");
1134 1606
1135 $BUTTONBAR->add (new CFClient::UI::Button 1607 $BUTTONBAR->add (new CFClient::UI::Button
1136 text => "Save Config", 1608 text => "Save Config",
1137 tooltip => "Saves the options chosen in the client setting, server settings and the window layout to be restored on later runs.", 1609 tooltip => "Saves the options chosen in the client setting, server settings and the window layout to be restored on later runs.",
1138 on_activate => sub { 1610 on_activate => sub {
1139 $::CFG->{layout} = CFClient::UI::get_layout; 1611 $::CFG->{layout} = CFClient::UI::get_layout;
1140 CFClient::write_cfg "$Crossfire::VARDIR/cfplusrc"; 1612 CFClient::write_cfg "$Crossfire::VARDIR/cfplusrc";
1141 status "Configuration Saved"; 1613 status "Configuration Saved";
1614 0
1142 }, 1615 },
1143 ); 1616 );
1144 1617
1145 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Help!", other => make_help_window, 1618 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Help!", other => help_window,
1146 tooltip => "View Documentation"); 1619 tooltip => "View Documentation");
1147
1148 $BUTTONBAR->add (new CFClient::UI::Flopper
1149 text => "Bindings",
1150 other => make_binding_window,
1151 tooltip => "Lets you delete bindings you have made with the recorder"
1152 );
1153 $BUTTONBAR->add (new CFClient::UI::Flopper text => "[Rec]", other => CFClient::Recorder::make_window,
1154 tooltip => "This feature lets you record a series of actions (eg. walking a path or ready a skill) and bind them to keys");
1155 1620
1156 $BUTTONBAR->add (new CFClient::UI::Button 1621 $BUTTONBAR->add (new CFClient::UI::Button
1157 text => "Quit", 1622 text => "Quit",
1158 tooltip => "Terminates the program", 1623 tooltip => "Terminates the program",
1159 on_activate => sub { 1624 on_activate => sub {
1160 if ($CONN) { 1625 if ($CONN) {
1161 open_quit_dialog; 1626 open_quit_dialog;
1162 } else { 1627 } else {
1163 exit; 1628 exit;
1164 } 1629 }
1630 0
1165 }, 1631 },
1166 ); 1632 );
1167 1633
1168 $BUTTONBAR->show; 1634 $BUTTONBAR->show;
1169 1635 $SETUP_DIALOG->show;
1170 $STATUSBOX->add ("Set video mode $WIDTH×$HEIGHT", timeout => 10, fg => [1, 1, 1, 0.5]);
1171
1172 $SERVER_SETUP->show;
1173 } 1636 }
1637
1638 $STATUSBOX->add ("Set video mode $WIDTH×$HEIGHT", timeout => 10, fg => [1, 1, 1, 0.5]);
1174} 1639}
1175 1640
1176sub video_shutdown { 1641sub video_shutdown {
1642 CFClient::OpenGL::shutdown;
1643
1177 undef $SDL_ACTIVE; 1644 undef $SDL_ACTIVE;
1178} 1645}
1179 1646
1180my @bgmusic = qw(game1.ogg game2.ogg game3.ogg game5.ogg game6.ogg ross1.ogg ross2.ogg ross3.ogg ross4.ogg ross5.ogg); #d# 1647my @bgmusic = qw(game1.ogg game2.ogg game3.ogg game5.ogg game6.ogg ross1.ogg ross2.ogg ross3.ogg ross4.ogg ross5.ogg); #d#
1181my $bgmusic;#TODO#hack#d# 1648my $bgmusic;#TODO#hack#d#
1245 1712
1246my %demo;#d# 1713my %demo;#d#
1247 1714
1248sub force_refresh { 1715sub force_refresh {
1249 $fps = $fps * 0.95 + 1 / (($NOW - $LAST_REFRESH) || 0.1) * 0.05; 1716 $fps = $fps * 0.95 + 1 / (($NOW - $LAST_REFRESH) || 0.1) * 0.05;
1250 debug sprintf "%3.2f", $fps; 1717 debug sprintf "%3.2f", $fps if $ENV{CFPLUS_DEBUG} & 4;
1251 1718
1252 $CFClient::UI::ROOT->draw; 1719 $CFClient::UI::ROOT->draw;
1253 1720
1254 $WANT_REFRESH = 0; 1721 $WANT_REFRESH = 0;
1255 $CAN_REFRESH = 0; 1722 $CAN_REFRESH = 0;
1310}; 1777};
1311 1778
1312 CFClient::SDL_GL_SwapBuffers; 1779 CFClient::SDL_GL_SwapBuffers;
1313} 1780}
1314 1781
1315my $refresh_watcher = Event->timer (after => 0, hard => 1, interval => 1 / $MAX_FPS, cb => sub { 1782my $refresh_watcher = Event->timer (after => 0, hard => 0, interval => 1 / $MAX_FPS, cb => sub {
1316 $NOW = time; 1783 $NOW = time;
1317 1784
1318 ($SDL_CB{$_->{type}} || sub { warn "unhandled event $_->{type}" })->($_) 1785 ($SDL_CB{$_->{type}} || sub { warn "unhandled event $_->{type}" })->($_)
1319 for CFClient::SDL_PollEvent; 1786 for CFClient::SDL_PollEvent;
1320 1787
1387############################################################################# 1854#############################################################################
1388 1855
1389$SIG{INT} = $SIG{TERM} = sub { exit }; 1856$SIG{INT} = $SIG{TERM} = sub { exit };
1390 1857
1391{ 1858{
1392 local $SIG{__DIE__} = sub { CFClient::fatal $_[0] if defined $^S && !$^S }; 1859 local $SIG{__DIE__} = sub {
1860 return unless defined $^S && !$^S;
1861 Carp::confess $_[1];#d#TODO: remove when stable
1862 CFClient::fatal $_[0];
1863 };
1393 1864
1394 CFClient::read_cfg "$Crossfire::VARDIR/cfplusrc"; 1865 CFClient::read_cfg "$Crossfire::VARDIR/cfplusrc";
1395 CFClient::UI::set_layout ($::CFG->{layout}); 1866 CFClient::UI::set_layout ($::CFG->{layout});
1396 1867
1397 my %DEF_CFG = ( 1868 my %DEF_CFG = (
1403 map_scale => 1, 1874 map_scale => 1,
1404 fow_enable => 1, 1875 fow_enable => 1,
1405 fow_intensity => 0.45, 1876 fow_intensity => 0.45,
1406 fow_smooth => 0, 1877 fow_smooth => 0,
1407 gui_fontsize => 1, 1878 gui_fontsize => 1,
1408 log_fontsize => 1, 1879 log_fontsize => 0.7,
1409 gauge_fontsize=> 1, 1880 gauge_fontsize=> 1,
1410 gauge_size => 0.35, 1881 gauge_size => 0.35,
1411 stat_fontsize => 1, 1882 stat_fontsize => 0.7,
1412 mapsize => 100, 1883 mapsize => 100,
1413 host => "crossfire.schmorp.de", 1884 host => "crossfire.schmorp.de",
1414 say_command => 'say', 1885 say_command => 'say',
1415 audio_enable => 1, 1886 audio_enable => 1,
1416 bgm_enable => 1, 1887 bgm_enable => 1,
1417 bgm_volume => 0.25, 1888 bgm_volume => 0.25,
1418 face_prefetch => 0, 1889 face_prefetch => 0,
1419 output_sync => 1, 1890 output_sync => 1,
1420 output_count => 1, 1891 output_count => 1,
1892 pickup => 0,
1421 ); 1893 );
1422 1894
1423 while (my ($k, $v) = each %DEF_CFG) { 1895 while (my ($k, $v) = each %DEF_CFG) {
1424 $CFG->{$k} = $v unless exists $CFG->{$k}; 1896 $CFG->{$k} = $v unless exists $CFG->{$k};
1425 } 1897 }
1472 video_init; 1944 video_init;
1473 audio_init; 1945 audio_init;
1474} 1946}
1475 1947
1476Event::loop; 1948Event::loop;
1949#CFClient::SDL_Quit;
1950#CFClient::_exit 0;
1477 1951
1478END { CFClient::SDL_Quit } 1952END { CFClient::SDL_Quit }
1479 1953
1480=head1 NAME 1954=head1 NAME
1481 1955
1488=head1 USAGE 1962=head1 USAGE
1489 1963
1490cfplus utilises OpenGL for all UI elements and the game. It is supposed to be used 1964cfplus utilises OpenGL for all UI elements and the game. It is supposed to be used
1491fullscreen and interactively. 1965fullscreen and interactively.
1492 1966
1967=head1 DEBUGGING
1968
1969
1970CFPLUS_DEBUG - environment variable
1971
1972 1 draw borders around widgets
1973 2 add low-level widget info to tooltips
1974 4 show fps
1975 8 suppress tooltips
1976
1493=head1 AUTHOR 1977=head1 AUTHOR
1494 1978
1495Marc Lehmann <crossfire@schmorp.de>, Robin Redeker <elmex@ta-sa.org> 1979Marc Lehmann <crossfire@schmorp.de>, Robin Redeker <elmex@ta-sa.org>
1496 1980
1497 1981

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines