--- deliantra/Deliantra-Client/bin/cfplus 2006/05/28 00:40:52 1.20
+++ deliantra/Deliantra-Client/bin/cfplus 2006/06/02 06:22:55 1.42
@@ -83,6 +83,8 @@
our $METASERVER;
our $LOGIN_BUTTON;
our $QUIT_DIALOG;
+our $HOST_ENTRY;
+our $SERVER_SETUP;
our $FLOORBOX;
our $GAUGES;
@@ -99,9 +101,15 @@
our $STATUSBOX;
our $DEBUG_STATUS;
+our $INV_WINDOW;
our $INV;
our $INVR;
-our $INVR_LBL;
+our $INV_RIGHT_HB;
+
+our $BIND_WINDOW;
+our $BIND_EDITOR;
+
+our $SPELL_LIST;
sub status {
$STATUSBOX->add (CFClient::UI::Label::escape $_[0], pri => -10, group => "status", timeout => 10, fg => [1, 1, 0, 1]);
@@ -109,13 +117,14 @@
sub debug {
$DEBUG_STATUS->set_text ($_[0]);
- my ($w, $h) = $DEBUG_STATUS->size_request;
- $DEBUG_STATUS->move ($WIDTH - $w, 0);
}
sub start_game {
status "logging in...";
+ $LOGIN_BUTTON->set_text ("Logout");
+ $SERVER_SETUP->hide;
+
my $mapsize = List::Util::min 32, List::Util::max 11, int $WIDTH * $CFG->{mapsize} * 0.01 / 32;
my ($host, $port) = split /:/, $CFG->{host};
@@ -153,12 +162,7 @@
if ($CONN) {
CFClient::lowdelay fileno $CONN->{fh};
- $LOGIN_BUTTON->set_text ("Logout");
status "login successful";
-
- $BUTTONBAR->{children}[1]->emit ("activate")
- if $BUTTONBAR->{children}[1]->{state};
-
} else {
status "unable to connect";
stop_game();
@@ -166,30 +170,33 @@
}
sub stop_game {
+ $LOGIN_BUTTON->set_text ("Login");
+ $SERVER_SETUP->show;
+ $INV_WINDOW->hide;
+ $LOGVIEW->hide;
+
return unless $CONN;
status "connection closed";
- $LOGIN_BUTTON->set_text ("Login");
+
$CONN->destroy;
$CONN = 0; # false, does not autovivify
-
- $BUTTONBAR->{children}[1]->emit ("activate")
- unless $BUTTONBAR->{children}[1]->{state};
}
sub client_setup {
my $dialog = new CFClient::UI::FancyFrame
- req_x => 1,
- req_y => $HEIGHT * (1/8),
- name => "client_setup",
+ x => 1,
+ y => $HEIGHT * (1/8),
+ name => "client_setup",
title => "Client Setup",
child => (my $vbox = new CFClient::UI::VBox);
+
$vbox->add (my $table = new CFClient::UI::Table expand => 1, col_expand => [0, 1]);
$table->add (0, 0, new CFClient::UI::Label valign => 0, align => 1, text => "Video Mode");
$table->add (1, 0, my $hbox = new CFClient::UI::HBox);
- $hbox->add (my $mode_slider = new CFClient::UI::Slider expand => 1, req_w => 100, range => [$CFG->{sdl_mode}, 0, $#SDL_MODES, 0, 1]);
+ $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]);
$hbox->add (my $mode_label = new CFClient::UI::Label align => 0, valign => 0, height => 0.8, template => "9999x9999");
$mode_slider->connect (changed => sub {
@@ -387,10 +394,10 @@
my $gh = int $HEIGHT * $CFG->{gauge_size};
my $win = new CFClient::UI::Frame (
- req_x => 0,
- req_y => -1,
- def_w => $WIDTH,
- def_h => $gh,
+ force_x => 0,
+ force_y => "max",
+ force_w => $WIDTH,
+ force_h => $gh,
);
$win->add (my $hbox = new CFClient::UI::HBox
@@ -436,12 +443,13 @@
$win
}
+
sub make_stats_window {
my $tgw = new CFClient::UI::FancyFrame
- req_y => $HEIGHT * (2/8),
- req_x => -1,
+ y => $HEIGHT * (2/8),
+ x => "max",
title => "Stats",
- name => "stats_window";
+ name => "stats_window";
$tgw->add (new CFClient::UI::Window child => my $vb = new CFClient::UI::VBox);
$vb->add ($STATWIDS->{title} = new CFClient::UI::Label valign => 0, align => -1, text => "Title:", expand => 1,
@@ -623,21 +631,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;
@@ -699,7 +695,8 @@
$table->add (0, $y, new CFClient::UI::VBox children => [
(new CFClient::UI::Button text => "Use", on_activate => sub {
- $HOST->set_text ($CFG->{host} = $host);
+ $HOST_ENTRY->set_text ($CFG->{host} = $host);
+ $METASERVER->toggle_visibility;
}),
(new CFClient::UI::Empty expand => 1),
]);
@@ -712,16 +709,31 @@
});
}
-sub server_setup {
+sub metaserver_dialog {
my $dialog = new CFClient::UI::FancyFrame
- x => $WIDTH * (1/3),
- y => $HEIGHT * (1/8),
- name => "server_setup",
- title => "Server Setup",
- child => (my $vbox = new CFClient::UI::VBox),
+ title => "Server List",
+ name => 'metaserver_dialog',
+ x => 'center',
+ y => 'center',
+ child => (my $vbox = new CFClient::UI::VBox),
on_visibility_change => sub {
- $_[0]->show_centered if $_[1]
- };
+ update_metaserver if $_[1];
+ },
+ ;
+
+ $vbox->add ($dialog->{table} = new CFClient::UI::Table);
+
+ $dialog
+}
+
+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),
+ ;
$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");
@@ -730,7 +742,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",
@@ -742,14 +754,12 @@
$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 },
);
}
@@ -776,7 +786,7 @@
$table->add (0, 7, new CFClient::UI::Label valign => 0, align => 1, text => "Map Size");
$table->add (1, 7, new CFClient::UI::Slider
- req_w => 100,
+ force_w => 100,
range => [$CFG->{mapsize}, 10, 100, 0, 1],
tooltip => "This is the size of the portion of the map update the server sends you. "
. "If you set this to a high value you will be able to see further, "
@@ -835,10 +845,10 @@
title => "Messages",
border_bg => [1, 1, 1, 1],
bg => [0, 0, 0, 0.75],
- req_x => -1,
- req_y => 0,
- def_w => int $::WIDTH / 3,
- def_h => int $::HEIGHT / 5,
+ x => "max",
+ y => 0,
+ force_w => $::WIDTH / 3,
+ force_h => $::HEIGHT / 5,
child => (my $vbox = new CFClient::UI::VBox);
$vbox->add ($LOGVIEW);
@@ -862,7 +872,12 @@
my ($input, $text) = @_;
$input->set_text ('');
- if ($text =~ /^\/(.*)/) {
+ if ($text =~ /^\/bind\s+(.*)$/) {
+ CFClient::Binder::open_binding_dialog (sub {
+ my ($mod, $sym) = @_;
+ $::CFG->{bindings}->{$mod}->{$sym} = [$1];
+ });
+ } elsif ($text =~ /^\/(.*)/) {
$::CONN->user_send ($1);
} else {
my $say_cmd = $::CFG->{say_command} || 'say';
@@ -880,7 +895,7 @@
$CONSOLE = {
window => $window,
- input => $input
+ input => $input,
};
$window
@@ -888,8 +903,11 @@
sub open_quit_dialog {
unless ($QUIT_DIALOG) {
-
- $QUIT_DIALOG = new CFClient::UI::FancyFrame title => "Really Quit?";
+ $QUIT_DIALOG = new CFClient::UI::FancyFrame
+ x => "center",
+ y => "center",
+ title => "Really Quit?",
+ ;
$QUIT_DIALOG->add (my $vb = new CFClient::UI::VBox expand => 1);
@@ -909,54 +927,148 @@
expand => 1,
on_activate => sub { exit },
);
-
- $QUIT_DIALOG->show_centered;
- } else {
- $QUIT_DIALOG->show_centered;
}
+
+ $QUIT_DIALOG->show;
}
sub make_inventory_window {
- my $invwin = new CFClient::UI::FancyFrame
- def_w => $WIDTH * (7/8),
- def_h => $HEIGHT * (7/8),
- title => "Inventory",
- name => "inventory_window",
+ my $invwin = $INV_WINDOW = new CFClient::UI::FancyFrame
+ x => "center",
+ y => "center",
+ force_w => $WIDTH * 9/10,
+ force_h => $HEIGHT * 9/10,
+ title => "Inventory",
+ ;
+
+ $invwin->add (my $hb = new CFClient::UI::HBox homogeneous => 1);
+
+ $hb->add (my $vb1 = new CFClient::UI::VBox);
+ $vb1->add (new CFClient::UI::Label align => 0, text => "Player");
+ $vb1->add ($INV = new CFClient::UI::Inventory expand => 1);
+
+ $hb->add (my $vb2 = new CFClient::UI::VBox);
+
+ $vb2->add ($INV_RIGHT_HB = new CFClient::UI::HBox);
+
+ $vb2->add ($INVR = new CFClient::UI::Inventory expand => 1);
+
+ # XXX: Call after $INVR = ... because set_opencont sets the items
+ CFClient::Protocol::set_opencont ($::CONN, 0, "Floor");
+
+ $invwin
+}
+
+sub make_spell_list {
+ $SPELL_LIST = new CFClient::UI::SpellList
+ force_w => $WIDTH * (9/10),
+ force_h => $HEIGHT * (9/10);
+ $SPELL_LIST
+}
+
+sub make_binding_window {
+ my $binding_list = new CFClient::UI::VBox;
+
+ my $refresh;
+ $refresh = sub {
+ $binding_list->clear ();
+
+ for my $mod (keys %{$::CFG->{bindings}}) {
+ for my $sym (keys %{$::CFG->{bindings}->{$mod}}) {
+ my $cmds = $::CFG->{bindings}->{$mod}->{$sym};
+ next unless ref $cmds eq 'ARRAY' and @$cmds > 0;
+
+ my $lbl = join "; ", @$cmds;
+ my $nam = CFClient::Binder::keycombo_to_name ($mod, $sym);
+ $binding_list->add (my $hb = new CFClient::UI::HBox);
+ $hb->add (new CFClient::UI::Button
+ text => "delete",
+ tooltip => "Deletes the binding",
+ on_activate => sub {
+ $binding_list->remove ($hb);
+ delete $::CFG->{bindings}->{$mod}->{$sym};
+ });
+
+ $hb->add (new CFClient::UI::Button
+ text => "edit",
+ tooltip => "Edits the binding",
+ on_activate => sub {
+ $::BIND_EDITOR->set_binding (
+ $mod, $sym, $::CFG->{bindings}->{$mod}->{$sym},
+ sub {
+ my ($nmod, $nsym, $ncmds) = @_;
+ delete $::CFG->{bindings}->{$mod}->{$sym};
+ $::CFG->{bindings}->{$nmod}->{$nsym} = $ncmds;
+ $refresh->();
+ $::BIND_WINDOW->show;
+ },
+ sub {
+ $::BIND_WINDOW->show;
+ });
+ $::BIND_EDITOR->show;
+ $::BIND_WINDOW->hide;
+ });
+
+ $hb->add (new CFClient::UI::Label text => "(Key: $nam)");
+ $hb->add (new CFClient::UI::Label text => $lbl, expand => 1);
+ }
+ }
+ };
+
+ $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 {
- $_[0]->show_centered if $_[1]
+ my ($self, $visible) = @_;
+ $refresh->() if $visible;
};
- $invwin->add (my $hb = new CFClient::UI::HBox expand => 1);
-
- $hb->add (my $vb1 = new CFClient::UI::VBox expand => 1);
- $vb1->add (my $lbl = new CFClient::UI::Label align => 0);
- $lbl->set_text ("Player");
- $vb1->add ($INV = new CFClient::UI::Inventory expand => 1);
-
- $hb->add (my $vb2 = new CFClient::UI::VBox expand => 1);
-
- $vb2->add (my $hb2 = new CFClient::UI::HBox);
- $hb2->add ($INVR_LBL = new CFClient::UI::Label align => 0, expand => 1);
- $hb2->add (new CFClient::UI::Button
- text => "Close",
- tooltip => "Close the currently open container (if one is open)",
+ $BIND_WINDOW->add (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,
+ tooltip => "This button opens the binding editor with an empty binding.",
on_activate => sub {
- $CONN->send ("apply $CONN->{open_container}")
- if $CONN->{open_container} != 0;
+ $::BIND_EDITOR->set_binding (undef, undef, [],
+ sub {
+ my ($mod, $sym, $cmds) = @_;
+ $::CFG->{bindings}->{$mod}->{$sym} = $cmds;
+ $refresh->();
+ $::BIND_WINDOW->show;
+ },
+ sub {
+ $::BIND_WINDOW->show;
+ });
+ $::BIND_WINDOW->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;
+ }
+ );
- $INVR_LBL->set_text ("Floor");
- $vb2->add ($INVR = new CFClient::UI::Inventory expand => 1);
-
- $invwin
+ $refresh->();
+ $BIND_WINDOW
}
sub make_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',
+ 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);
@@ -1027,19 +1139,30 @@
} else {
# create the widgets
- $DEBUG_STATUS = new CFClient::UI::Label padding => 0, z => 100, req_x => -1;
+ $DEBUG_STATUS = new CFClient::UI::Label
+ padding => 0,
+ z => 100,
+ force_x => "max",
+ force_y => 0;
$DEBUG_STATUS->show;
-
+
+ $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]);
(new CFClient::UI::Frame
bg => [0, 0, 0, 0.4],
- req_y => -1,
+ force_x => 0,
+ force_y => "max",
child => $STATUSBOX,
)->show;
CFClient::UI::FancyFrame->new (
+ title => "Mini Map",
+ name => "mapmap",
+ x => 0,
+ y => $FONTSIZE + 8,
border_bg => [1, 1, 1, 192/255],
bg => [1, 1, 1, 0],
child => ($MAPMAP = new CFClient::MapWidget::MapMap
@@ -1072,7 +1195,7 @@
tooltip => "Server Log. This text viewer contains all the messages sent by the server.",
;
- $BUTTONBAR = new CFClient::UI::HBox;
+ $BUTTONBAR = new CFClient::UI::HBox x => 0, y => 0;
$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.");
@@ -1086,14 +1209,15 @@
$BUTTONBAR->add (new CFClient::UI::Flopper text => "Stats Window", other => make_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 :).");
+ 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::Button
text => "Save Config",
tooltip => "Saves the options chosen in the client setting, server settings and the window layout to be restored on later runs.",
on_activate => sub {
$::CFG->{layout} = CFClient::UI::get_layout;
- CFClient::write_cfg "$Crossfire::VARDIR/pclientrc";
+ CFClient::write_cfg "$Crossfire::VARDIR/cfplusrc";
status "Configuration Saved";
},
);
@@ -1101,6 +1225,22 @@
$BUTTONBAR->add (new CFClient::UI::Flopper text => "Help!", other => make_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",
@@ -1114,16 +1254,9 @@
);
$BUTTONBAR->show;
+ $SERVER_SETUP->show;
$STATUSBOX->add ("Set video mode $WIDTH×$HEIGHT", timeout => 10, fg => [1, 1, 1, 0.5]);
-
- # delay till geometry is constant
- $CFClient::UI::ROOT->on_post_alloc (startup => sub {
- $BUTTONBAR->{children}[1]->emit ("activate"); # pop up server setup
- my $widget = $GAUGES->{win};
- $widget->move (0, $HEIGHT - $widget->{h});#d# to in toplevel
- });
- force_refresh ();
}
}
@@ -1201,7 +1334,7 @@
sub force_refresh {
$fps = $fps * 0.95 + 1 / (($NOW - $LAST_REFRESH) || 0.1) * 0.05;
- debug sprintf "%3.2f", $fps;
+ debug sprintf "%3.2f", $fps if $ENV{CFPLUS_DEBUG} & 4;
$CFClient::UI::ROOT->draw;
@@ -1343,9 +1476,9 @@
$SIG{INT} = $SIG{TERM} = sub { exit };
{
- local $SIG{__DIE__} = sub { CFClient::fatal $_[0] };
+ local $SIG{__DIE__} = sub { CFClient::fatal $_[0] if defined $^S && !$^S };
- CFClient::read_cfg "$Crossfire::VARDIR/pclientrc";
+ CFClient::read_cfg "$Crossfire::VARDIR/cfplusrc";
CFClient::UI::set_layout ($::CFG->{layout});
my %DEF_CFG = (
@@ -1433,7 +1566,7 @@
=head1 NAME
-pclient - A Crossfire+ and Crossfire game client
+cfplus - A Crossfire+ and Crossfire game client
=head1 SYNOPSIS
@@ -1441,9 +1574,19 @@
=head1 USAGE
-Pclient utilises OpenGL for all UI elements and the game. It is supposed to be used
+cfplus utilises OpenGL for all UI elements and the game. It is supposed to be used
fullscreen and interactively.
+=head1 DEBUGGING
+
+
+CFPLUS_DEBUG - environment variable
+
+ 1 draw borders around widgets
+ 2 add low-level widget info to tooltips
+ 4 show fps
+ 8 suppress tooltips
+
=head1 AUTHOR
Marc Lehmann , Robin Redeker