--- deliantra/Deliantra-Client/bin/cfplus 2006/06/01 03:42:58 1.39 +++ deliantra/Deliantra-Client/bin/cfplus 2006/06/12 12:28:06 1.68 @@ -27,7 +27,6 @@ if %PAR::LibCache; use Time::HiRes 'time'; -use Pod::POM; use Event; use Crossfire; @@ -41,8 +40,11 @@ use CFClient::UI; use CFClient::MapWidget; +$SIG{QUIT} = sub { Carp::cluck "QUIT" }; + $Event::DIED = sub { # TODO: display dialog box or so + Carp::confess $_[1];#d#TODO: remove when stable CFClient::error $_[1]; }; @@ -83,8 +85,17 @@ our $METASERVER; our $LOGIN_BUTTON; our $QUIT_DIALOG; -our $SERVER_SETUP; +our $HOST_ENTRY; +our $SERVER_INFO; + +our $SETUP_DIALOG; +our $SETUP_NOTEBOOK; +our $SETUP_SERVER; +our $SETUP_KEYBOARD; +our $SETUP_SPELLS; +our $STATS_WINDOW; +our $MESSAGE_WINDOW; our $FLOORBOX; our $GAUGES; our $STATWIDS; @@ -105,10 +116,9 @@ our $INVR; our $INV_RIGHT_HB; -our $BIND_WINDOW; our $BIND_EDITOR; -our $SPELL_LIST; +our $PICKUP_CFG; sub status { $STATUSBOX->add (CFClient::UI::Label::escape $_[0], pri => -10, group => "status", timeout => 10, fg => [1, 1, 0, 1]); @@ -118,11 +128,192 @@ $DEBUG_STATUS->set_text ($_[0]); } +sub destroy_query_dialog { + (delete $_[0]{query_dialog})->destroy + if $_[0]{query_dialog}; +} + +# server query dialog +sub server_query { + my ($conn, $flags, $prompt) = @_; + + $conn->{query_dialog} = my $dialog = new CFClient::UI::FancyFrame + x => "center", + y => "center", + title => "Server Query", + child => my $vbox = new CFClient::UI::VBox, + ; + + my @dialog = my $label = new CFClient::UI::Label + max_w => $::WIDTH * 0.4, + ellipsise => 0, + text => $prompt; + + if ($flags & CS_QUERY_YESNO) { + push @dialog, my $hbox = new CFClient::UI::HBox; + + $hbox->add (new CFClient::UI::Button + text => "No", + on_activate => sub { + $conn->send ("reply n"); + $dialog->destroy; + } + ); + $hbox->add (new CFClient::UI::Button + text => "Yes", + on_activate => sub { + $conn->send ("reply y"); + destroy_query_dialog $conn; + }, + ); + + $dialog->focus_in; + + } elsif ($flags & CS_QUERY_SINGLECHAR) { + $dialog->{tooltip} = "Press a key (click on the entry to make sure it has keyboard focus)"; + + if ($prompt =~ /Now choose a character|Press any key for the next race/i) { + $MESSAGE_WINDOW->show; + + unshift @dialog, new CFClient::UI::Label + max_w => $::WIDTH * 0.4, + ellipsise => 0, + markup => "\nOr use your keyboard:\n"; + + unshift @dialog, my $table = new CFClient::UI::Table; + + $table->add (0, 0, new CFClient::UI::Button + text => "Next Race", + on_activate => sub { + $conn->send ("reply n"); + destroy_query_dialog $conn; + }, + ); + $table->add (2, 0, new CFClient::UI::Button + text => "Accept", + on_activate => sub { + $conn->send ("reply d"); + destroy_query_dialog $conn; + }, + ); + + unshift @dialog, new CFClient::UI::Label + max_w => $::WIDTH * 0.4, + ellipsise => 0, + markup => + "Character Creation: Race\n\n" + . "Look at the Messages window to see a description of this race " + . "(or hover with your mouse over the bottommost entry in the status area in the lower left area of the screen) " + . "and the center of the screen to see how this race looks like " + . "(this is below this dialog window, you may need to click on the display area to make it visible).\n\n" + . "You can look at another race, or accept this race (you will come back to this race eventually, " + . "so you can take your time making this important choice." + ; + + } elsif ($prompt =~ /roll new stats/) { + if (my $stat = delete $conn->{stat_change_with}) { + $conn->send ("reply $stat"); + destroy_query_dialog $conn; + return; + } + + $STATS_WINDOW->show; + $MESSAGE_WINDOW->hide; + + unshift @dialog, new CFClient::UI::Label + max_w => $::WIDTH * 0.4, + ellipsise => 0, + markup => "\nOr use your keyboard:\n"; + + unshift @dialog, my $table = new CFClient::UI::Table; + + # left: re-roll + $table->add (0, 0, new CFClient::UI::Button + text => "Roll Again", + on_activate => sub { + $conn->send ("reply y"); + destroy_query_dialog $conn; + }, + ); + + # center: swap stats + my ($sw1, $sw2) = map +(new CFClient::UI::Combobox + value => $_, + options => [ + [1 => "Str", "Strength ($conn->{stat}{+CS_STAT_STR})"], + [2 => "Dex", "Dexterity ($conn->{stat}{+CS_STAT_DEX})"], + [3 => "Con", "Constitution ($conn->{stat}{+CS_STAT_CON})"], + [4 => "Int", "Intelligence ($conn->{stat}{+CS_STAT_INT})"], + [5 => "Wis", "Wisdom ($conn->{stat}{+CS_STAT_WIS})"], + [6 => "Pow", "Power ($conn->{stat}{+CS_STAT_POW})"], + [7 => "Cha", "Charisma ($conn->{stat}{+CS_STAT_CHA})"], + ], + ), 1 .. 2; + + $table->add (2, 0, new CFClient::UI::Button + text => "Swap Stats", + on_activate => sub { + $conn->{stat_change_with} = $sw2->{value}; + $conn->send ("reply $sw1->{value}"); + destroy_query_dialog $conn; + }, + ); + $table->add (2, 1, new CFClient::UI::HBox children => [$sw1, $sw2]); + + # right: accept + $table->add (4, 0, new CFClient::UI::Button + text => "Accept", + on_activate => sub { + $conn->send ("reply n"); + $STATS_WINDOW->hide; + destroy_query_dialog $conn; + }, + ); + + unshift @dialog, new CFClient::UI::Label + max_w => $::WIDTH * 0.4, + ellipsise => 0, + markup => + "Character Creation: Stats\n\n" + . "Look at the Stats window to see your basic stats " + . "(first column: 1 strength, 2 dexterity, 3 constitution, 4 intelligence, 5 wisdom, 6 power and 7 charisma).\n\n" + . "You can create another set of stats, swap two stat values with each other or accept the stats as they are now and continue. " + . "Race selection will influence those values later on." + ; + } + + push @dialog, my $entry = new CFClient::UI::Entry + on_changed => sub { + $conn->send ("reply $_[1]"); + destroy_query_dialog $conn; + }, + ; + + $entry->focus_in; + + } else { + $dialog->{tooltip} = "Enter the reply and press return (click on the entry to make sure it has keyboard focus)"; + + push @dialog, my $entry = new CFClient::UI::Entry + $flags & CS_QUERY_HIDEINPUT ? (hidden => "*") : (), + on_activate => sub { + $conn->send ("reply $_[1]"); + destroy_query_dialog $conn; + }, + ; + + $entry->focus_in; + } + + $vbox->add (@dialog); + $dialog->show; +} + sub start_game { status "logging in..."; $LOGIN_BUTTON->set_text ("Logout"); - $SERVER_SETUP->hide; + $SETUP_DIALOG->hide; my $mapsize = List::Util::min 32, List::Util::max 11, int $WIDTH * $CFG->{mapsize} * 0.01 / 32; @@ -144,6 +335,7 @@ statusbox => $STATUSBOX, map => $MAP, mapmap => $MAPMAP, + query => \&server_query, sound_play => sub { my ($x, $y, $soundnum, $type) = @_; @@ -170,25 +362,22 @@ sub stop_game { $LOGIN_BUTTON->set_text ("Login"); - $SERVER_SETUP->show; + $SETUP_NOTEBOOK->set_current_page ($SETUP_SERVER); + $SETUP_DIALOG->show; $INV_WINDOW->hide; - $LOGVIEW->hide; + $SETUP_SPELLS->clear_spells; return unless $CONN; status "connection closed"; + destroy_query_dialog $CONN; $CONN->destroy; $CONN = 0; # false, does not autovivify } -sub client_setup { - my $dialog = new CFClient::UI::FancyFrame - x => 1, - y => $HEIGHT * (1/8), - name => "client_setup", - title => "Client Setup", - child => (my $vbox = new CFClient::UI::VBox); +sub graphics_setup { + my $vbox = new CFClient::UI::VBox; $vbox->add (my $table = new CFClient::UI::Table expand => 1, col_expand => [0, 1]); @@ -323,6 +512,16 @@ } ); + $vbox +} + +sub audio_setup { + my $vbox = new CFClient::UI::VBox; + + $vbox->add (my $table = new CFClient::UI::Table expand => 1, col_expand => [0, 1]); + + my $row = 0; + $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Audio Enable"); $table->add (1, $row++, new CFClient::UI::CheckBox state => $CFG->{audio_enable}, @@ -362,19 +561,7 @@ } ); - $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Chat Command"); - $table->add (1, $row++, my $saycmd = new CFClient::UI::Entry - text => $CFG->{say_command}, - tooltip => "This is the command that will be used if you write a line in the message window entry or press \" in the map window. " - . "Usually you want to enter something like 'say' or 'shout' or 'gsay' here. " - . "But you could also set it to tell playername to only chat with that user.", - on_changed => sub { - my ($self, $value) = @_; - $CFG->{say_command} = $value; - } - ); - - $dialog + $vbox } sub set_stats_window_fontsize { @@ -442,8 +629,35 @@ $win } +sub debug_setup { + my $table = new CFClient::UI::Table; + + $table->add (0, 0, new CFClient::UI::Label text => "Widget Borders"); + $table->add (1, 0, new CFClient::UI::CheckBox on_changed => sub { $ENV{CFPLUS_DEBUG} ^= 1 }); + $table->add (0, 1, new CFClient::UI::Label text => "Tooltip Widget Info"); + $table->add (1, 1, new CFClient::UI::CheckBox on_changed => sub { $ENV{CFPLUS_DEBUG} ^= 2 }); + $table->add (0, 2, new CFClient::UI::Label text => "Show FPS"); + $table->add (1, 2, new CFClient::UI::CheckBox on_changed => sub { $ENV{CFPLUS_DEBUG} ^= 4 }); + $table->add (0, 3, new CFClient::UI::Label text => "Suppress Tooltips"); + $table->add (1, 3, new CFClient::UI::CheckBox on_changed => sub { $ENV{CFPLUS_DEBUG} ^= 8 }); + + my @default_smooth = (0.05, 0.13, 0.05, 0.13, 0.30, 0.13, 0.05, 0.13, 0.05); + + for my $x (0..2) { + for my $y (0 .. 2) { + $table->add ($x + 3, $y, + new CFClient::UI::Entry + text => $default_smooth[$x * 3 + $y], + on_changed => sub { $MAP->{smooth_matrix}[$x * 3 + $y] = $_[1] if $MAP; 0 }, + ); + } + } + + + $table +} -sub make_stats_window { +sub stats_window { my $tgw = new CFClient::UI::FancyFrame y => $HEIGHT * (2/8), x => "max", @@ -557,8 +771,8 @@ $tgw } -sub formsep { - reverse join ",", grep length, split /(...)/, reverse $_[0] * 1 +sub formsep($) { + scalar reverse join ",", unpack "(A3)*", reverse $_[0] * 1 } sub update_stats_window { @@ -630,21 +844,9 @@ for keys %tbl; } -sub metaserver_dialog { - my $dialog = new CFClient::UI::FancyFrame - title => "Server List", - child => (my $vbox = new CFClient::UI::VBox); - - $vbox->add ($dialog->{table} = new CFClient::UI::Table); - - $dialog -} - my $METASERVER_ATIME; sub update_metaserver { - my ($HOST) = @_; - return if $METASERVER_ATIME > time; $METASERVER_ATIME = time + 60; @@ -675,9 +877,19 @@ $table->clear; - my @col = qw(Use #Users Host Uptime Version Description); - $table->add ($_, 0, new CFClient::UI::Label align => 0, fg => [1, 1, 0], text => $col[$_]) - for 0 .. $#col; + my @tip = ( + "The current number of users logged in on the server.", + "The hostname of the server.", + "The time this server has been running without being restarted.", + "The server software version - a '+' indicates a Crossfire+ server.", + "Short information about this server provided by its admins.", + ); + my @col = qw(#Users Host Uptime Version Description); + $table->add ($_, 0, new CFClient::UI::Label + can_hover => 1, can_events => 1, + align => 0, fg => [1, 1, 0], + text => $col[$_], tooltip => $tip[$_]) + for 0 .. $#col; my @align = qw(1 0 1 1 -1); @@ -704,30 +916,56 @@ $y++; - $table->add (0, $y, new CFClient::UI::VBox children => [ - (new CFClient::UI::Button text => "Use", on_activate => sub { - $HOST->set_text ($CFG->{host} = $host); - }), + $table->add (scalar @$m, $y, new CFClient::UI::VBox children => [ + (new CFClient::UI::Button + text => "Use", + tooltip => "Put this server into the Host:Port field", + on_activate => sub { + $HOST_ENTRY->set_text ($CFG->{host} = $host); + $METASERVER->hide; + }, + ), (new CFClient::UI::Empty expand => 1), ]); - $table->add ($_ + 1, $y, new CFClient::UI::Label - ellipsise => 0, align => $align[$_], text => $m->[$_], fontsize => 0.8) + $table->add ($_, $y, new CFClient::UI::Label + ellipsise => 0, + align => $align[$_], + text => $m->[$_], + tooltip => $tip[$_], + can_hover => 1, + can_events => 1, + fontsize => 0.8) for 0 .. $#$m; } } }); } -sub server_setup { - my $dialog = $SERVER_SETUP = new CFClient::UI::FancyFrame - x => "center", - y => "center", - name => "server_setup", - title => "Server Setup", - child => (my $vbox = new CFClient::UI::VBox), +sub metaserver_dialog { + my $dialog = new CFClient::UI::FancyFrame + title => "Server List", + name => 'metaserver_dialog', + x => 'center', + y => 'center', + z => 3, + force_h => $::HEIGHT * 0.4, + child => (my $vbox = new CFClient::UI::VBox), + on_visibility_change => sub { + update_metaserver if $_[1]; + }, ; + $dialog->{table} = new CFClient::UI::Table; + + $vbox->add (new CFClient::UI::ScrolledWindow expand => 1, child => $dialog->{table}); + + $dialog +} + +sub server_setup { + my $vbox = new CFClient::UI::VBox; + $vbox->add (my $table = new CFClient::UI::Table expand => 1, col_expand => [0, 1]); $table->add (0, 2, new CFClient::UI::Label valign => 0, align => 1, text => "Host:Port"); @@ -735,7 +973,7 @@ $table->add (1, 2, my $vbox = new CFClient::UI::VBox); $vbox->add ( - my $HOST = new CFClient::UI::Entry + $HOST_ENTRY = new CFClient::UI::Entry expand => 1, text => $CFG->{host}, tooltip => "The hostname or ip address of the Crossfire(+) server to connect to", @@ -747,14 +985,13 @@ $METASERVER = metaserver_dialog; - $vbox->add (new CFClient::UI::Flopper - expand => 1, - text => "Server List", - other => $METASERVER, + $vbox->add (new CFClient::UI::Button + expand => 1, + text => "Server List", + other => $METASERVER, tooltip => "Show a list of available crossfire servers", - on_open => sub { - update_metaserver $HOST; - } + on_activate => sub { $METASERVER->toggle_visibility }, + on_visibility_change => sub { $METASERVER->hide unless $_[1] }, ); } @@ -831,7 +1068,28 @@ }, ); - $dialog + $table->add (0, 12, new CFClient::UI::Label valign => 0, align => 1, text => "Chat Command"); + $table->add (1, 12, my $saycmd = new CFClient::UI::Entry + text => $CFG->{say_command}, + tooltip => "This is the command that will be used if you write a line in the message window entry or press \" in the map window. " + . "Usually you want to enter something like 'say' or 'shout' or 'gsay' here. " + . "But you could also set it to tell playername to only chat with that user.", + on_changed => sub { + my ($self, $value) = @_; + $CFG->{say_command} = $value; + } + ); + + $vbox->add (new CFClient::UI::Label + text => "Server Info", + fontsize => 1.2, + padding_y => 8, + fg => [1, 1, 0, 1], + ); + + $vbox->add ($SERVER_INFO = new CFClient::UI::Label ellipsise => 0); + + $vbox } sub message_window { @@ -842,8 +1100,8 @@ bg => [0, 0, 0, 0.75], x => "max", y => 0, - force_w => $::WIDTH / 3, - force_h => $::HEIGHT / 5, + force_w => $::WIDTH * 0.4, + force_h => $::HEIGHT * 0.5, child => (my $vbox = new CFClient::UI::VBox); $vbox->add ($LOGVIEW); @@ -867,12 +1125,7 @@ my ($input, $text) = @_; $input->set_text (''); - if ($text =~ /^\/bind\s+(.*)$/) { - CFClient::Binder::open_binding_dialog (sub { - my ($mod, $sym) = @_; - $::CFG->{bindings}->{$mod}->{$sym} = [$1]; - }); - } elsif ($text =~ /^\/(.*)/) { + if ($text =~ /^\/(.*)/) { $::CONN->user_send ($1); } else { my $say_cmd = $::CFG->{say_command} || 'say'; @@ -901,6 +1154,7 @@ $QUIT_DIALOG = new CFClient::UI::FancyFrame x => "center", y => "center", + z => 50, title => "Really Quit?", ; @@ -927,7 +1181,98 @@ $QUIT_DIALOG->show; } -sub make_inventory_window { +sub autopickup_setup { + my $table = new CFClient::UI::Table; + + for ( + ["General", 0, 0, + ["Enable autopickup" => PICKUP_NEWMODE], + ["Inhibit autopickup" => PICKUP_INHIBIT], + ["Stop before pickup" => PICKUP_STOP], + ["Debug autopickup" => PICKUP_DEBUG], + ], + ["Weapons", 0, 6, + ["All weapons" => PICKUP_ALLWEAPON], + ["Missile weapons" => PICKUP_MISSILEWEAPON], + ["Bows" => PICKUP_BOW], + ["Arrows" => PICKUP_ARROW], + ], + ["Armour", 0, 12, + ["Helmets" => PICKUP_HELMET], + ["Shields" => PICKUP_SHIELD], + ["Body Armour" => PICKUP_ARMOUR], + ["Boots" => PICKUP_BOOTS], + ["Gloves" => PICKUP_GLOVES], + ["Cloaks" => PICKUP_CLOAK], + ], + + ["Readables", 2, 2, + ["Spellbooks" => PICKUP_SPELLBOOK], + ["Skillscrolls" => PICKUP_SKILLSCROLL], + ["Normal Books/Scrolls" => PICKUP_READABLES], + ], + ["Misc", 2, 7, + ["Food" => PICKUP_FOOD], + ["Drinks" => PICKUP_DRINK], + ["Valuables (Money, Gems)" => PICKUP_VALUABLES], + ["Keys" => PICKUP_KEY], + ["Magical Items" => PICKUP_MAGICAL], + ["Potions" => PICKUP_POTION], + ["Magic Devices" => PICKUP_MAGIC_DEVICE], + ["Ignore cursed" => PICKUP_NOT_CURSED], + ["Jewelery" => PICKUP_JEWELS], + ], + ["Weight/Value ratio", 2, 17] + ) + { + my ($title, $x, $y, @bits) = @$_; + $table->add ($x, $y, new CFClient::UI::Label text => $title, align => 1, fg => [1, 1, 0]); + + for (@bits) { + ++$y; + + my $mask = $_->[1]; + $table->add ($x , $y, new CFClient::UI::Label text => $_->[0], align => 1, expand => 1); + $table->add ($x+1, $y, new CFClient::UI::CheckBox + state => $CFG->{pickup} & $mask, + on_changed => sub { + my ($box, $value) = @_; + + if ($value) { + $::CFG->{pickup} |= $mask; + } else { + $::CFG->{pickup} &= ~$mask; + } + + $::CONN->send_command ("pickup $::CFG->{pickup}") + if defined $::CONN; + }); + } + } + + $table->add (2, 18, new CFClient::UI::ValSlider + range => [0, 0, 16, 1, 1], + to_value => sub { ">= " . 5 * $_[0] }, + on_changed => sub { + my ($slider, $value) = @_; + + $::CFG->{pickup} &= ~0x7; + $::CFG->{pickup} |= int $value + if $value; + 1; + }); + $table->add (3, 18, new CFClient::UI::Button + text => "set", + on_activate => sub { + $::CONN->send_command ("pickup $::CFG->{pickup}") + if defined $::CONN; + 1; + }); + + $table +} + +sub inventory_window { my $invwin = $INV_WINDOW = new CFClient::UI::FancyFrame x => "center", y => "center", @@ -954,14 +1299,11 @@ $invwin } -sub make_spell_list { - $SPELL_LIST = new CFClient::UI::SpellList - force_w => $WIDTH * (9/10), - force_h => $HEIGHT * (9/10); - $SPELL_LIST +sub spell_setup { + new CFClient::UI::SpellList } -sub make_binding_window { +sub keyboard_setup { my $binding_list = new CFClient::UI::VBox; my $refresh; @@ -995,13 +1337,15 @@ delete $::CFG->{bindings}->{$mod}->{$sym}; $::CFG->{bindings}->{$nmod}->{$nsym} = $ncmds; $refresh->(); - $::BIND_WINDOW->show; + $SETUP_NOTEBOOK->set_current_page ($SETUP_KEYBOARD); + $SETUP_DIALOG->show; }, sub { - $::BIND_WINDOW->show; + $SETUP_NOTEBOOK->set_current_page ($SETUP_KEYBOARD); + $SETUP_DIALOG->show; }); $::BIND_EDITOR->show; - $::BIND_WINDOW->hide; + $SETUP_DIALOG->hide; }); $hb->add (new CFClient::UI::Label text => "(Key: $nam)"); @@ -1010,20 +1354,10 @@ } }; - $BIND_WINDOW = new CFClient::UI::FancyFrame - title => "Bindings", - x => "center", - y => "center", - def_w => int $WIDTH * 9/10, - def_h => int $HEIGHT * 9/10, - on_visibility_change => sub { - my ($self, $visible) = @_; - $refresh->() if $visible; - }; - - $BIND_WINDOW->add (my $vb = new CFClient::UI::VBox); + my $vb = new CFClient::UI::VBox; $vb->add ($binding_list); $vb->add (my $hb = new CFClient::UI::HBox); + $hb->add (new CFClient::UI::Button text => "record new", expand => 1, @@ -1034,64 +1368,80 @@ my ($mod, $sym, $cmds) = @_; $::CFG->{bindings}->{$mod}->{$sym} = $cmds; $refresh->(); - $::BIND_WINDOW->show; + $SETUP_NOTEBOOK->set_current_page ($SETUP_KEYBOARD); + $SETUP_DIALOG->show; }, sub { - $::BIND_WINDOW->show; - }); - $::BIND_WINDOW->hide; + $SETUP_NOTEBOOK->set_current_page ($SETUP_KEYBOARD); + $SETUP_DIALOG->show; + }, + ); + $SETUP_DIALOG->hide; $::BIND_EDITOR->show; }, ); + $hb->add (new CFClient::UI::Button text => "close", tooltip => "Closes the binding window", expand => 1, on_activate => sub { - $::BIND_WINDOW->hide; + $SETUP_DIALOG->hide; } ); $refresh->(); - $BIND_WINDOW + + $vb } -sub make_help_window { +sub help_window { my $win = new CFClient::UI::FancyFrame - def_w => int $WIDTH * 7/8, - def_h => int $HEIGHT * 7/8, - title => "Documentation"; + x => 'center', + y => 'center', + z => 2, + name => 'doc_browser', + force_w => int $WIDTH * 7/8, + force_h => int $HEIGHT * 7/8, + title => "Documentation"; $win->add (my $vbox = new CFClient::UI::VBox); $vbox->add (my $buttons = new CFClient::UI::HBox); - $vbox->add (my $viewer = new CFClient::UI::TextView expand => 1, fontsize => 0.8); + $vbox->add (my $viewer = new CFClient::UI::TextScroller + expand => 1, fontsize => 0.8, padding_x => 4); - for ( - [intro => "Introduction"], - [manual => "Manual"], - [command_help => "Commands"], - [skill_help => "Skills"], - ) { - my ($pod, $label) = @$_; - - $buttons->add (new CFClient::UI::Button - text => $label, - on_activate => sub { - my $parser = new Pod::POM; - my $pom = $parser->parse_file (CFClient::find_rcfile "pod/$pod.pod"); + $buttons->add (new CFClient::UI::Label text => "Choose a document to display: "); + $buttons->add (my $combo = new CFClient::UI::Combobox + value => undef, + options => [ + [intro => "Introduction"], + [manual => "Manual"], + [skill_help => "Skills"], + [command_help => "Commands"], + [dmcommand_help => "DM Commands"], + [COPYING => "License Terms"], + ], + on_changed => sub { + my ($self, $pod) = @_; - $viewer->clear; - - $viewer->add_paragraph ([1, 1, 1, 1], $_->[1], $_->[0]) - for @{ CFClient::pod_to_pango_list $pom }; + my $pom = CFClient::load_pod CFClient::find_rcfile "pod/$pod.pod", + doc_viewer => 1, sub { CFClient::pod_to_pango_list $_[0] }; - $viewer->set_offset (0); - }, - ); - } + $viewer->clear; + + $viewer->add_paragraph ([1, 1, 1, 1], $_->[1], $_->[0]) + for @$pom; - $viewer->add_paragraph ([1, 1, 0, 1], "Use one of the buttons above to display a document."); + $viewer->set_offset (0); + }, + on_visibility_change => sub { + my ($self, $visible) = @_; + return unless $visible; + return if $self->{value}; + $self->set_value ("intro"); + }, + ); $win } @@ -1141,7 +1491,7 @@ $BIND_EDITOR = new CFClient::UI::BindEditor (x => "max", y => 0); $STATUSBOX = new CFClient::UI::Statusbox; - $STATUSBOX->add ("Use Alt-Enter to toggle fullscreen mode", pri => -100, color => [1, 1, 1, 0.8]); + $STATUSBOX->add ("Use Alt-Enter to toggle fullscreen mode", timeout => 864000, pri => -100, color => [1, 1, 1, 0.8]); (new CFClient::UI::Frame bg => [0, 0, 0, 0.4], @@ -1151,6 +1501,8 @@ )->show; CFClient::UI::FancyFrame->new ( + title => "Map", + name => "mapmap", x => 0, y => $FONTSIZE + 8, border_bg => [1, 1, 1, 192/255], @@ -1176,31 +1528,64 @@ $MAPWIDGET->show; $MAPWIDGET->focus_in; - $LOGVIEW = new CFClient::UI::TextView + $LOGVIEW = new CFClient::UI::TextScroller expand => 1, font => $FONT_FIXED, fontsize => $::CFG->{log_fontsize}, + indent => -4, can_hover => 1, can_events => 1, tooltip => "Server Log. This text viewer contains all the messages sent by the server.", ; - $BUTTONBAR = new CFClient::UI::HBox x => 0, y => 0; + $SETUP_DIALOG = new CFClient::UI::FancyFrame + title => "Setup", + name => "setup_dialog", + x => 'center', + y => 'center', + z => 2, + force_w => $::WIDTH * 0.6, + force_h => $::HEIGHT * 0.6, + ; + + $SETUP_DIALOG->add ($SETUP_NOTEBOOK = new CFClient::UI::Notebook expand => 1, debug => 1, + filter => new CFClient::UI::ScrolledWindow expand => 1, scroll_y => 1); + + $SETUP_NOTEBOOK->add (Server => $SETUP_SERVER = server_setup, + "Configure the server to play on, your username, password and other server-related options."); + $SETUP_NOTEBOOK->add (Pickup => autopickup_setup, + "Configure autopickup settings, i.e. which items you will pick up automatically when walking (or running) over them."); + $SETUP_NOTEBOOK->add (Graphics => graphics_setup, + "Configure the video mode, performance, fonts and other graphical aspects of the game."); + $SETUP_NOTEBOOK->add (Audio => audio_setup, + "Configure the use of audio, sound effects and background music."); + $SETUP_NOTEBOOK->add (Keyboard => $SETUP_KEYBOARD = keyboard_setup, + "Lets you define, edit and delete bindings." + . "There is a shortcut for making bindings: Left Control + Insert opens the binding editor " + . "with nothing set and the recording started. After doing the actions you " + . "want to record press Insert and you will be asked to press a key-combo. " + . "After pressing the combo the binding will be saved automatically and the " + . "binding editor closes"); + $SETUP_NOTEBOOK->add (Spells => $SETUP_SPELLS = spell_setup, + "Displays all spells you have and lets you edit keyboard shortcuts for them."); + $SETUP_NOTEBOOK->add (Debug => debug_setup, + "Some debuggign options. Do not ask."); + + $BUTTONBAR = new CFClient::UI::Buttonbar x => 0, y => 0, z => 200; # put on top - $BUTTONBAR->add (new CFClient::UI::Flopper text => "Client Setup", other => client_setup, - tooltip => "Toggles a dialog where you can configure various aspects of the client, such as graphics mode, performance, and audio options."); - $BUTTONBAR->add (new CFClient::UI::Flopper text => "Server Setup", other => server_setup, - tooltip => "Toggles a dialog where you can configure the server to play on, your username, password and other server-related options."); - $BUTTONBAR->add (new CFClient::UI::Flopper text => "Message Window", other => message_window, + $BUTTONBAR->add (new CFClient::UI::Flopper text => "Setup", other => $SETUP_DIALOG, + tooltip => "Toggles a dialog where you can configure all aspects of this client."); + + $BUTTONBAR->add (new CFClient::UI::Flopper text => "Message Window", other => $MESSAGE_WINDOW = message_window, tooltip => "Toggles the server message log, where the client collects all messages from the server."); 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 - $BUTTONBAR->add (new CFClient::UI::Flopper text => "Stats Window", other => make_stats_window, + $BUTTONBAR->add (new CFClient::UI::Flopper text => "Stats Window", other => $STATS_WINDOW = stats_window, tooltip => "Toggles the statistics window, where all your Stats and Resistances are being displayed at all times."); - $BUTTONBAR->add (new CFClient::UI::Flopper text => "Inventory", other => make_inventory_window, - tooltip => "Toggles the inventory window, where you can manage your loot (or treaures :)." - ."You can also hit the Tab-key to show/hide the Inventory."); + $BUTTONBAR->add (new CFClient::UI::Flopper text => "Inventory", other => inventory_window, + tooltip => "Toggles the inventory window, where you can manage your loot (or treasures :). " + . "You can also hit the Tab-key to show/hide the Inventory."); $BUTTONBAR->add (new CFClient::UI::Button text => "Save Config", @@ -1212,25 +1597,9 @@ }, ); - $BUTTONBAR->add (new CFClient::UI::Flopper text => "Help!", other => make_help_window, + $BUTTONBAR->add (new CFClient::UI::Flopper text => "Help!", other => help_window, tooltip => "View Documentation"); - $BUTTONBAR->add (new CFClient::UI::Flopper - text => "Bindings", - other => make_binding_window, - tooltip => - "Lets you define, edit and delete bindings." - ."There is a shortcut for making bindings: LCTRL+Insert opens the binding editor " - ."with nothing set and the recording started. After doing the actions you " - ."want to record press Insert and you will be asked to press a key-combo." - ."After pressing the combo the binding will be saved automatically and the " - ."binding editor closes"); - - $BUTTONBAR->add (new CFClient::UI::Flopper - text => "Spells", - other => make_spell_list, - tooltip => "The spell list"); - $BUTTONBAR->add (new CFClient::UI::Button text => "Quit", tooltip => "Terminates the program", @@ -1244,10 +1613,10 @@ ); $BUTTONBAR->show; - $SERVER_SETUP->show; - - $STATUSBOX->add ("Set video mode $WIDTH×$HEIGHT", timeout => 10, fg => [1, 1, 1, 0.5]); + $SETUP_DIALOG->show; } + + $STATUSBOX->add ("Set video mode $WIDTH×$HEIGHT", timeout => 10, fg => [1, 1, 1, 0.5]); } sub video_shutdown { @@ -1389,7 +1758,7 @@ CFClient::SDL_GL_SwapBuffers; } -my $refresh_watcher = Event->timer (after => 0, hard => 1, interval => 1 / $MAX_FPS, cb => sub { +my $refresh_watcher = Event->timer (after => 0, hard => 0, interval => 1 / $MAX_FPS, cb => sub { $NOW = time; ($SDL_CB{$_->{type}} || sub { warn "unhandled event $_->{type}" })->($_) @@ -1466,7 +1835,11 @@ $SIG{INT} = $SIG{TERM} = sub { exit }; { - local $SIG{__DIE__} = sub { CFClient::fatal $_[0] if defined $^S && !$^S }; + local $SIG{__DIE__} = sub { + return unless defined $^S && !$^S; + Carp::confess $_[1];#d#TODO: remove when stable + CFClient::fatal $_[0]; + }; CFClient::read_cfg "$Crossfire::VARDIR/cfplusrc"; CFClient::UI::set_layout ($::CFG->{layout}); @@ -1482,10 +1855,10 @@ fow_intensity => 0.45, fow_smooth => 0, gui_fontsize => 1, - log_fontsize => 1, + log_fontsize => 0.7, gauge_fontsize=> 1, gauge_size => 0.35, - stat_fontsize => 1, + stat_fontsize => 0.7, mapsize => 100, host => "crossfire.schmorp.de", say_command => 'say', @@ -1495,6 +1868,7 @@ face_prefetch => 0, output_sync => 1, output_count => 1, + pickup => 0, ); while (my ($k, $v) = each %DEF_CFG) {