--- deliantra/Deliantra-Client/bin/cfplus 2006/05/27 20:00:40 1.16
+++ deliantra/Deliantra-Client/bin/cfplus 2006/06/18 17:23:36 1.75
@@ -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,7 +85,17 @@
our $METASERVER;
our $LOGIN_BUTTON;
our $QUIT_DIALOG;
+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;
@@ -99,9 +111,14 @@
our $STATUSBOX;
our $DEBUG_STATUS;
+our $INV_WINDOW;
our $INV;
our $INVR;
-our $INVR_LBL;
+our $INV_RIGHT_HB;
+
+our $BIND_EDITOR;
+
+our $PICKUP_CFG;
sub status {
$STATUSBOX->add (CFClient::UI::Label::escape $_[0], pri => -10, group => "status", timeout => 10, fg => [1, 1, 0, 1]);
@@ -109,16 +126,207 @@
sub debug {
$DEBUG_STATUS->set_text ($_[0]);
- my ($w, $h) = $DEBUG_STATUS->size_request;
- $DEBUG_STATUS->move ($WIDTH - $w, 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;
+ 0
+ }
+ );
+ $hbox->add (new CFClient::UI::Button
+ text => "Yes",
+ on_activate => sub {
+ $conn->send ("reply y");
+ destroy_query_dialog $conn;
+ 0
+ },
+ );
+
+ $dialog->grab_focus;
+
+ } 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;
+ 0
+ },
+ );
+ $table->add (2, 0, new CFClient::UI::Button
+ text => "Accept",
+ on_activate => sub {
+ $conn->send ("reply d");
+ destroy_query_dialog $conn;
+ 0
+ },
+ );
+
+ 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;
+ 0
+ },
+ );
+
+ # 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;
+ 0
+ },
+ );
+ $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;
+ 0
+ },
+ );
+
+ 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;
+ 0
+ },
+ ;
+
+ $entry->grab_focus;
+
+ } 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;
+ 0
+ },
+ ;
+
+ $entry->grab_focus;
+ }
+
+ $vbox->add (@dialog);
+ $dialog->show;
}
sub start_game {
status "logging in...";
+ $LOGIN_BUTTON->set_text ("Logout");
+ $SETUP_DIALOG->hide;
+
my $mapsize = List::Util::min 32, List::Util::max 11, int $WIDTH * $CFG->{mapsize} * 0.01 / 32;
- my ($host, $port) = split /:/, $CFG->{host};
+ my ($host, $port) = split /:/, $CFG->{profile}{default}{host};
$MAP = new CFClient::Map $mapsize, $mapsize;
@@ -126,8 +334,8 @@
new CFClient::Protocol
host => $host,
port => $port || 13327,
- user => $CFG->{user},
- pass => $CFG->{password},
+ user => $CFG->{profile}{default}{user},
+ pass => $CFG->{profile}{default}{password},
mapw => $mapsize,
maph => $mapsize,
@@ -136,6 +344,7 @@
statusbox => $STATUSBOX,
map => $MAP,
mapmap => $MAPMAP,
+ query => \&server_query,
sound_play => sub {
my ($x, $y, $soundnum, $type) = @_;
@@ -153,12 +362,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,28 +370,30 @@
}
sub stop_game {
+ $LOGIN_BUTTON->set_text ("Login");
+ $SETUP_NOTEBOOK->set_current_page ($SETUP_SERVER);
+ $SETUP_DIALOG->show;
+ $INV_WINDOW->hide;
+ $SETUP_SPELLS->clear_spells;
+
return unless $CONN;
status "connection closed";
- $LOGIN_BUTTON->set_text ("Login");
+
+ destroy_query_dialog $CONN;
$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
- 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]);
$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 {
@@ -204,60 +410,46 @@
$table->add (1, $row++, new CFClient::UI::CheckBox
state => $CFG->{fullscreen},
tooltip => "Bring the client into fullscreen mode.",
- connect_changed => sub {
- my ($self, $value) = @_;
- $CFG->{fullscreen} = $value;
- }
+ on_changed => sub { my ($self, $value) = @_; $CFG->{fullscreen} = $value; 0 }
);
$table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Fast & Ugly");
$table->add (1, $row++, new CFClient::UI::CheckBox
state => $CFG->{fast},
tooltip => "Lower the visual quality considerably to speed up rendering.",
- connect_changed => sub {
- my ($self, $value) = @_;
- $CFG->{fast} = $value;
- }
+ on_changed => sub { my ($self, $value) = @_; $CFG->{fast} = $value; 0 }
);
$table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Map Scale");
$table->add (1, $row++, new CFClient::UI::Slider
range => [(log $CFG->{map_scale}) / (log 2), -3, 1, 0, 1],
tooltip => "Enlarge or shrink the displayed map. Changes are instant.",
- connect_changed => sub {
- my ($self, $value) = @_;
- $CFG->{map_scale} = 2 ** $value;
- }
+ on_changed => sub { my ($self, $value) = @_; $CFG->{map_scale} = 2 ** $value; 0 }
);
$table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Fog of War");
$table->add (1, $row++, new CFClient::UI::CheckBox
state => $CFG->{fow_enable},
tooltip => "Fog-of-War marks areas that cannot be seen by the player. Changes are instant.",
- connect_changed => sub {
- my ($self, $value) = @_;
- $CFG->{fow_enable} = $value;
- }
+ on_changed => sub { my ($self, $value) = @_; $CFG->{fow_enable} = $value; 0 }
);
$table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "FoW Intensity");
$table->add (1, $row++, new CFClient::UI::Slider
range => [$CFG->{fow_intensity}, 0, 1, 0, 1 / 256],
tooltip => "Fog of War Lightness. The higher the intensity, the lighter the Fog-of-War color. Changes are instant.",
- connect_changed => sub {
- my ($self, $value) = @_;
- $CFG->{fow_intensity} = $value;
- }
+ on_changed => sub { my ($self, $value) = @_; $CFG->{fow_intensity} = $value; 0 }
);
$table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "FoW Smooth");
$table->add (1, $row++, new CFClient::UI::CheckBox
state => $CFG->{fow_smooth},
tooltip => "Smooth the Fog-of-War a bit to make it more realistic. Changes are instant.",
- connect_changed => sub {
+ on_changed => sub {
my ($self, $value) = @_;
$CFG->{fow_smooth} = $value;
status "Fog of War smoothing requires OpenGL 1.2 or higher" if $CFClient::OpenGL::GL_VERSION < 1.2;
+ 0
}
);
@@ -265,14 +457,14 @@
$table->add (1, $row++, new CFClient::UI::Slider
range => [$CFG->{gui_fontsize}, 0.5, 2, 0, 0.1],
tooltip => "The base font size used by most GUI elements that do not have their own setting.",
- connect_changed => sub { $CFG->{gui_fontsize} = $_[1] },
+ on_changed => sub { $CFG->{gui_fontsize} = $_[1]; 0 },
);
$table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Message Fontsize");
$table->add (1, $row++, new CFClient::UI::Slider
range => [$CFG->{log_fontsize}, 0.5, 2, 0, 0.1],
tooltip => "The font size used by the message/server log window only. Changes are instant.",
- connect_changed => sub { $LOGVIEW->set_fontsize ($CFG->{log_fontsize} = $_[1]) },
+ on_changed => sub { $LOGVIEW->set_fontsize ($CFG->{log_fontsize} = $_[1]); 0 },
);
$table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Stats Fontsize");
@@ -280,9 +472,10 @@
$table->add (1, $row++, new CFClient::UI::Slider
range => [$CFG->{stat_fontsize}, 0.5, 2, 0, 0.1],
tooltip => "The font size used by the statistics window only. Changes are instant.",
- connect_changed => sub {
+ on_changed => sub {
$CFG->{stat_fontsize} = $_[1];
&set_stats_window_fontsize;
+ 0
}
);
@@ -290,41 +483,52 @@
$table->add (1, $row++, new CFClient::UI::Slider
range => [$CFG->{gauge_fontsize}, 0.5, 2, 0, 0.1],
tooltip => "Adjusts the fontsize of the gauges at the bottom right. Changes are instant.",
- connect_changed => sub {
+ on_changed => sub {
$CFG->{gauge_fontsize} = $_[1];
&set_gauge_window_fontsize;
+ 0
}
);
$table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Gauge size");
$table->add (1, $row++, new CFClient::UI::Slider
- range => [$CFG->{gauge_size}, 0.2, 0.8],
- tooltip => "Adjust the size of the stats gauges at the bottom right. Changes are instant.",
- connect_changed => sub {
+ range => [$CFG->{gauge_size}, 0.2, 0.8],
+ tooltip => "Adjust the size of the stats gauges at the bottom right. Changes are instant.",
+ on_changed => sub {
$CFG->{gauge_size} = $_[1];
$GAUGES->{win}->set_size ($WIDTH, int $HEIGHT * $CFG->{gauge_size});
+ 0
}
);
$table->add (1, $row++, new CFClient::UI::Button
expand => 1, align => 0, text => "Apply",
tooltip => "Apply the video settings",
- connect_activate => sub {
+ on_activate => sub {
video_shutdown ();
video_init ();
+ 0
}
);
+ $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},
tooltip => "Master Audio Enable. If enabled, sound effects and music will be played. If disabled, no audio will be used and the soundcard will not be opened.",
- connect_changed => sub {
- $CFG->{audio_enable} = $_[1];
- }
+ on_changed => sub { $CFG->{audio_enable} = $_[1]; 0 }
);
# $table->add (0, 9, new CFClient::UI::Label valign => 0, align => 1, text => "Effects Volume");
-# $table->add (1, 8, new CFClient::UI::Slider range => [$CFG->{effects_volume}, 0, 128, 1], connect_changed => sub {
+# $table->add (1, 8, new CFClient::UI::Slider range => [$CFG->{effects_volume}, 0, 128, 1], on_changed => sub {
# $CFG->{effects_volume} = $_[1];
# });
$table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Background Music");
@@ -332,41 +536,25 @@
$hbox->add (new CFClient::UI::CheckBox
expand => 1, state => $CFG->{bgm_enable},
tooltip => "If enabled, playing of background music is enabled. If disabled, no background music will be played.",
- connect_changed => sub {
- $CFG->{bgm_enable} = $_[1];
- }
+ on_changed => sub { $CFG->{bgm_enable} = $_[1]; 0 }
);
$hbox->add (new CFClient::UI::Slider
expand => 1, range => [$CFG->{bgm_volume}, 0, 1, 0, 1/128],
tooltip => "The volume of the background music. Changes are instant.",
- connect_changed => sub {
- $CFG->{bgm_volume} = $_[1];
- CFClient::MixMusic::volume $_[1] * 128;
- }
+ on_changed => sub { $CFG->{bgm_volume} = $_[1]; CFClient::MixMusic::volume $_[1] * 128; 0 }
);
$table->add (1, $row++, new CFClient::UI::Button
expand => 1, align => 0, text => "Apply",
tooltip => "Apply the audio settings",
- connect_activate => sub {
+ on_activate => sub {
audio_shutdown ();
audio_init ();
+ 0
}
);
- $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.",
- connect_changed => sub {
- my ($self, $value) = @_;
- $CFG->{say_command} = $value;
- }
- );
-
- $dialog
+ $vbox
}
sub set_stats_window_fontsize {
@@ -385,9 +573,10 @@
my $gh = int $HEIGHT * $CFG->{gauge_size};
my $win = new CFClient::UI::Frame (
- req_y => -1,
- user_w => $WIDTH,
- user_h => $gh,
+ force_x => 0,
+ force_y => "max",
+ force_w => $WIDTH,
+ force_h => $gh,
);
$win->add (my $hbox = new CFClient::UI::HBox
@@ -433,8 +622,41 @@
$win
}
-sub make_stats_window {
- my $tgw = new CFClient::UI::FancyFrame title => "Stats", name => "stats_window";
+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; 0 });
+ $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; 0 });
+ $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; 0 });
+ $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; 0 });
+
+ 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 stats_window {
+ my $tgw = new CFClient::UI::FancyFrame
+ y => $HEIGHT * (2/8),
+ x => "max",
+ title => "Stats",
+ name => "stats_window",
+ has_close_button => 1;
$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,
@@ -543,8 +765,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 {
@@ -590,47 +812,34 @@
$STATWIDS->{m_weight}->set_text (sprintf "Max weight: %.1fkg", $stats->{+CS_STAT_WEIGHT_LIM} / 1000);
- # TODO: replace by CS_STAT_RES_xxx constants
my %tbl = (
- phys => 100,
- magic => 101,
- fire => 102,
- elec => 103,
- cold => 104,
- conf => 105,
- acid => 106,
- drain => 107,
- ghit => 108,
- pois => 109,
- slow => 110,
- para => 111,
- tund => 112,
- fear => 113,
- depl => 113,
- deat => 115,
- holyw => 116,
- blind => 117,
+ phys => CS_STAT_RES_PHYS,
+ magic => CS_STAT_RES_MAG,
+ fire => CS_STAT_RES_FIRE,
+ elec => CS_STAT_RES_ELEC,
+ cold => CS_STAT_RES_COLD,
+ conf => CS_STAT_RES_CONF,
+ acid => CS_STAT_RES_ACID,
+ drain => CS_STAT_RES_DRAIN,
+ ghit => CS_STAT_RES_GHOSTHIT,
+ pois => CS_STAT_RES_POISON,
+ slow => CS_STAT_RES_SLOW,
+ para => CS_STAT_RES_PARA,
+ tund => CS_STAT_TURN_UNDEAD,
+ fear => CS_STAT_RES_FEAR,
+ depl => CS_STAT_RES_DEPLETE,
+ deat => CS_STAT_RES_DEATH,
+ holyw => CS_STAT_RES_HOLYWORD,
+ blind => CS_STAT_RES_BLIND,
);
$STATWIDS->{"res_$_"}->set_text (sprintf "%d%", $stats->{$tbl{$_}})
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;
@@ -661,9 +870,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);
@@ -690,27 +909,58 @@
$y++;
- $table->add (0, $y, new CFClient::UI::VBox children => [
- (new CFClient::UI::Button text => "Use", connect_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->{profile}{default}{host} = $host);
+ $METASERVER->hide;
+ 0
+ },
+ ),
(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 {
+sub metaserver_dialog {
my $dialog = new CFClient::UI::FancyFrame
- name => "server_setup",
- title => "Server Setup",
- child => (my $vbox = new CFClient::UI::VBox);
-
+ 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];
+ 0
+ },
+ ;
+
+ $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");
@@ -718,63 +968,53 @@
$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},
+ text => $CFG->{profile}{default}{host},
tooltip => "The hostname or ip address of the Crossfire(+) server to connect to",
- connect_changed => sub {
+ on_changed => sub {
my ($self, $value) = @_;
- $CFG->{host} = $value;
+ $CFG->{profile}{default}{host} = $value;
+ 0
}
);
$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",
- connect_open => sub {
- update_metaserver $HOST;
- }
+ on_activate => sub { $METASERVER->toggle_visibility; 0 },
+ on_visibility_change => sub { $METASERVER->hide unless $_[1]; 0 },
);
}
$table->add (0, 4, new CFClient::UI::Label valign => 0, align => 1, text => "Username");
$table->add (1, 4, new CFClient::UI::Entry
- text => $CFG->{user},
+ text => $CFG->{profile}{default}{user},
tooltip => "The name of your character on the server",
- connect_changed => sub {
- my ($self, $value) = @_;
- $CFG->{user} = $value;
- }
+ on_changed => sub { my ($self, $value) = @_; $CFG->{profile}{default}{user} = $value }
);
$table->add (0, 5, new CFClient::UI::Label valign => 0, align => 1, text => "Password");
$table->add (1, 5, new CFClient::UI::Entry
- text => $CFG->{password},
+ text => $CFG->{profile}{default}{password},
hidden => 1,
tooltip => "The password for your character",
- connect_changed => sub {
- my ($self, $value) = @_;
- $CFG->{password} = $value;
- }
+ on_changed => sub { my ($self, $value) = @_; $CFG->{profile}{default}{password} = $value }
);
$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, "
. "but you also increase bandwidth requirements and latency. "
. "This option is only used once at log-in.",
- connect_changed => sub {
- my ($self, $value) = @_;
-
- $CFG->{mapsize} = $self->{range}[0] = $value = int $value;
- },
+ on_changed => sub { my ($self, $value) = @_; $CFG->{mapsize} = $self->{range}[0] = $value = int $value; 0 },
);
$table->add (0, 8, new CFClient::UI::Label valign => 0, align => 1, text => "Face Prefetch");
@@ -787,34 +1027,57 @@
. "It also uses up server bandwidth on every connect, "
. "so only set it if you really need to prefetch images. "
. "This option can be set and unset any time.",
- connect_changed => sub { $CFG->{face_prefetch} = $_[1] },
+ on_changed => sub { $CFG->{face_prefetch} = $_[1]; 0 },
);
$table->add (0, 9, new CFClient::UI::Label valign => 0, align => 1, text => "Output-Count");
$table->add (1, 9, new CFClient::UI::Entry
text => $CFG->{output_count},
tooltip => "Should be set to 1 unless you know what you are doing. This option is only used once at log-in.",
- connect_changed => sub { $CFG->{output_count} = $_[1] },
+ on_changed => sub { $CFG->{output_count} = $_[1]; 0 },
);
$table->add (0, 10, new CFClient::UI::Label valign => 0, align => 1, text => "Output-Sync");
$table->add (1, 10, new CFClient::UI::Entry
text => $CFG->{output_sync},
tooltip => "Should be set to 1 unless you know what you are doing. This option is only used once at log-in.",
- connect_changed => sub { $CFG->{output_sync} = $_[1] },
+ on_changed => sub { $CFG->{output_sync} = $_[1]; 0 },
);
$table->add (1, 11, $LOGIN_BUTTON = new CFClient::UI::Button
expand => 1,
align => 0,
text => "Login",
- connect_activate => sub {
+ on_activate => sub {
$CONN ? stop_game
: start_game;
+ 0
},
);
- $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;
+ 0
+ }
+ );
+
+ $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 {
@@ -823,9 +1086,12 @@
title => "Messages",
border_bg => [1, 1, 1, 1],
bg => [0, 0, 0, 0.75],
- user_w => int $::WIDTH / 3,
- user_h => int $::HEIGHT / 5,
- child => (my $vbox = new CFClient::UI::VBox);
+ x => "max",
+ y => 0,
+ force_w => $::WIDTH * 0.4,
+ force_h => $::HEIGHT * 0.5,
+ child => (my $vbox = new CFClient::UI::VBox),
+ has_close_button => 1;
$vbox->add ($LOGVIEW);
@@ -834,7 +1100,7 @@
. "from the client setup will be prepended (e.g. shout, chat...). "
. "If you prepend a slash (/), you will submit a command instead (similar to IRC). "
. "A better way to submit commands (and the occasional chat command) is often the map command completer.",
- connect_focus_in => sub {
+ on_focus_in => sub {
my ($input, $prev_focus) = @_;
delete $input->{refocus_map};
@@ -843,8 +1109,10 @@
$input->{refocus_map} = 1;
}
delete $input->{auto_activated};
+
+ 0
},
- connect_activate => sub {
+ on_activate => sub {
my ($input, $text) = @_;
$input->set_text ('');
@@ -858,15 +1126,19 @@
delete $input->{refocus_map};
$MAPWIDGET->focus_in
}
+
+ 0
},
- connect_escape => sub {
- $MAPWIDGET->focus_in
+ on_escape => sub {
+ $MAPWIDGET->grab_focus;
+
+ 0
},
);
$CONSOLE = {
window => $window,
- input => $input
+ input => $input,
};
$window
@@ -874,8 +1146,12 @@
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",
+ z => 50,
+ title => "Really Quit?",
+ ;
$QUIT_DIALOG->add (my $vb = new CFClient::UI::VBox expand => 1);
@@ -888,83 +1164,300 @@
$hb->add (new CFClient::UI::Button
text => "Ok",
expand => 1,
- connect_activate => sub { $QUIT_DIALOG->hide },
+ on_activate => sub { $QUIT_DIALOG->hide; 0 },
);
$hb->add (new CFClient::UI::Button
text => "Quit anyway",
expand => 1,
- connect_activate => sub { exit },
+ on_activate => sub { exit },
);
+ }
- $QUIT_DIALOG->show_centered;
- } else {
- $QUIT_DIALOG->show_centered;
+ $QUIT_DIALOG->show;
+}
+
+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;
+
+ 0
+ });
+ }
}
+
+ $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;
+ 0
+ });
+
+ $table
}
-sub make_inventory_window {
- my $invwin = new CFClient::UI::FancyFrame
- user_w => $WIDTH * (7/8), user_h => $HEIGHT * (7/8), title => "Inventory", name => "inventory_window";
-
- $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 (new CFClient::UI::Button
- text => "Close",
- tooltip => "Close the currently open container (if one is open)",
- connect_activate => sub {
- $CONN->send ("apply $CONN->{open_container}")
- if $CONN->{open_container} != 0;
- },
- );
- $hb2->add ($INVR_LBL = new CFClient::UI::Label align => 0);
+sub 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",
+ has_close_button => 1,
+ ;
+
+ $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);
- $INVR_LBL->set_text ("Floor");
$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_help_window {
+sub spell_setup {
+ new CFClient::UI::SpellList
+}
+
+sub keyboard_setup {
+ my $binding_list = new CFClient::UI::VBox;
+
+ my $refresh;
+ $refresh = sub {
+ $binding_list->clear ();
+
+ for my $mod (keys %{$::CFG->{profile}{default}{bindings}}) {
+ for my $sym (keys %{$::CFG->{profile}{default}{bindings}{$mod}}) {
+ my $cmds = $::CFG->{profile}{default}{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->{profile}{default}{bindings}{$mod}{$sym};
+ 0
+ });
+
+ $hb->add (new CFClient::UI::Button
+ text => "edit",
+ tooltip => "Edits the binding",
+ on_activate => sub {
+ $::BIND_EDITOR->set_binding (
+ $mod, $sym, $::CFG->{profile}{default}{bindings}{$mod}{$sym},
+ sub {
+ my ($nmod, $nsym, $ncmds) = @_;
+ delete $::CFG->{profile}{default}{bindings}{$mod}{$sym};
+ $::CFG->{profile}{default}{bindings}{$nmod}{$nsym} = $ncmds;
+ $refresh->();
+ $SETUP_NOTEBOOK->set_current_page ($SETUP_KEYBOARD);
+ $SETUP_DIALOG->show;
+ },
+ sub {
+ $SETUP_NOTEBOOK->set_current_page ($SETUP_KEYBOARD);
+ $SETUP_DIALOG->show;
+ });
+ $::BIND_EDITOR->show;
+ $SETUP_DIALOG->hide;
+ 0
+ });
+
+ $hb->add (new CFClient::UI::Label text => "(Key: $nam)");
+ $hb->add (new CFClient::UI::Label text => $lbl, expand => 1);
+ }
+ }
+ };
+
+ my $vb = new CFClient::UI::VBox;
+ $vb->add (my $hb = new CFClient::UI::HBox);
+ $hb->add (new CFClient::UI::Label text => "only shift-up stops fire");
+ $hb->add (new CFClient::UI::CheckBox
+ expand => 1,
+ state => $CFG->{shift_fire_stop},
+ tooltip => "If this checkbox is enabled you will stop fire only if you stop pressing shift",
+ on_changed => sub {
+ my ($cbox, $value) = @_;
+ $CFG->{shift_fire_stop} = $value;
+ 0
+ });
+
+ $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 {
+ $::BIND_EDITOR->set_binding (undef, undef, [],
+ sub {
+ my ($mod, $sym, $cmds) = @_;
+ $::CFG->{profile}{default}{bindings}{$mod}{$sym} = $cmds;
+ $refresh->();
+ $SETUP_NOTEBOOK->set_current_page ($SETUP_KEYBOARD);
+ $SETUP_DIALOG->show;
+ },
+ sub {
+ $SETUP_NOTEBOOK->set_current_page ($SETUP_KEYBOARD);
+ $SETUP_DIALOG->show;
+ },
+ );
+ $SETUP_DIALOG->hide;
+ $::BIND_EDITOR->show;
+ 0
+ },
+ );
+
+ $hb->add (new CFClient::UI::Button
+ text => "close",
+ tooltip => "Closes the binding window",
+ expand => 1,
+ on_activate => sub {
+ $SETUP_DIALOG->hide;
+ 0
+ }
+ );
+
+ $refresh->();
+
+ $vb
+}
+
+sub help_window {
my $win = new CFClient::UI::FancyFrame
- user_w => $WIDTH * (7/8), user_h => $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);
-
- for (
- [intro => "Introduction"],
- [manual => "Manual"],
- [command_help => "Commands"],
- [skill_help => "Skills"],
- ) {
- my ($pod, $label) = @$_;
+ $vbox->add (my $viewer = new CFClient::UI::TextScroller
+ expand => 1, fontsize => 0.8, padding_x => 4);
- $buttons->add (new CFClient::UI::Button
- text => $label,
- connect_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);
+ 0
+ },
+ on_visibility_change => sub {
+ my ($self, $visible) = @_;
+ return unless $visible;
+ return if $self->{value};
+ $self->set_value ("intro");
+ 0
+ },
+ );
$win
}
@@ -1004,19 +1497,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]);
+ $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],
- req_y => -1,
+ force_x => 0,
+ force_y => "max",
child => $STATUSBOX,
)->show;
CFClient::UI::FancyFrame->new (
+ title => "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
@@ -1030,7 +1534,7 @@
if ($CONSOLE) {
$CONSOLE->{input}->{auto_activated} = 1;
- $CONSOLE->{input}->focus_in;
+ $CONSOLE->{input}->grab_focus;
if ($preset && $CONSOLE->{input}->get_text eq '') {
$CONSOLE->{input}->set_text ($preset);
@@ -1038,73 +1542,105 @@
}
});
$MAPWIDGET->show;
- $MAPWIDGET->focus_in;
+ $MAPWIDGET->grab_focus;
- $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;
+ $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,
+ has_close_button => 1,
+ ;
+
+ $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 key bindings."
+ . "There is a shortcut for making bindings: 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 debuggin' options. Do not ask.");
- $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 = new CFClient::UI::Buttonbar x => 0, y => 0, z => 200; # put on top
+
+ $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 :).");
+ $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",
tooltip => "Saves the options chosen in the client setting, server settings and the window layout to be restored on later runs.",
- connect_activate => sub {
+ on_activate => sub {
$::CFG->{layout} = CFClient::UI::get_layout;
- CFClient::write_cfg "$Crossfire::VARDIR/pclientrc";
+ CFClient::write_cfg "$Crossfire::VARDIR/cfplusrc";
status "Configuration Saved";
+ 0
},
);
- $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::Button
- text => "Quit",
- tooltip => "Terminates the program",
- connect_activate => sub {
+ text => "Quit",
+ tooltip => "Terminates the program",
+ on_activate => sub {
if ($CONN) {
open_quit_dialog;
} else {
exit;
}
+ 0
},
);
$BUTTONBAR->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 ();
+ $SETUP_DIALOG->show;
}
+
+ $STATUSBOX->add ("Set video mode $WIDTH×$HEIGHT", timeout => 10, fg => [1, 1, 1, 0.5]);
}
sub video_shutdown {
+ CFClient::OpenGL::shutdown;
+
undef $SDL_ACTIVE;
}
@@ -1178,7 +1714,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;
@@ -1243,7 +1779,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}" })->($_)
@@ -1320,41 +1856,48 @@
$SIG{INT} = $SIG{TERM} = sub { exit };
{
- local $SIG{__DIE__} = sub { CFClient::fatal $_[0] };
+ 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/pclientrc";
+ CFClient::read_cfg "$Crossfire::VARDIR/cfplusrc";
CFClient::UI::set_layout ($::CFG->{layout});
my %DEF_CFG = (
- sdl_mode => 0,
- width => 640,
- height => 480,
- fullscreen => 0,
- fast => 0,
- map_scale => 1,
- fow_enable => 1,
- fow_intensity => 0.45,
- fow_smooth => 0,
- gui_fontsize => 1,
- log_fontsize => 1,
- gauge_fontsize=> 1,
- gauge_size => 0.35,
- stat_fontsize => 1,
- mapsize => 100,
- host => "crossfire.schmorp.de",
- say_command => 'say',
- audio_enable => 1,
- bgm_enable => 1,
- bgm_volume => 0.25,
- face_prefetch => 0,
- output_sync => 1,
- output_count => 1,
+ sdl_mode => 0,
+ width => 640,
+ height => 480,
+ fullscreen => 0,
+ fast => 0,
+ map_scale => 1,
+ fow_enable => 1,
+ fow_intensity => 0.45,
+ fow_smooth => 0,
+ gui_fontsize => 1,
+ log_fontsize => 0.7,
+ gauge_fontsize => 1,
+ gauge_size => 0.35,
+ stat_fontsize => 0.7,
+ mapsize => 100,
+ say_command => 'say',
+ audio_enable => 1,
+ bgm_enable => 1,
+ bgm_volume => 0.25,
+ face_prefetch => 0,
+ output_sync => 1,
+ output_count => 1,
+ pickup => 0,
+ default => "profile", # default profile
);
-
+
while (my ($k, $v) = each %DEF_CFG) {
$CFG->{$k} = $v unless exists $CFG->{$k};
}
+ $CFG->{profile}{default}{host} ||= "crossfire.schmorp.de";
+
sdl_init;
@SDL_MODES = reverse
@@ -1405,12 +1948,14 @@
}
Event::loop;
+#CFClient::SDL_Quit;
+#CFClient::_exit 0;
END { CFClient::SDL_Quit }
=head1 NAME
-pclient - A Crossfire+ and Crossfire game client
+cfplus - A Crossfire+ and Crossfire game client
=head1 SYNOPSIS
@@ -1418,9 +1963,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