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

Comparing deliantra/Deliantra-Client/bin/pclient (file contents):
Revision 1.160 by root, Sat Apr 22 23:11:34 2006 UTC vs.
Revision 1.178 by root, Tue Apr 25 08:39:18 2006 UTC

1#!/opt/bin/perl 1#!/opt/bin/perl
2 2
3use strict; 3use strict;
4use utf8; 4use utf8;
5
6BEGIN {
7 if (%PAR::LibCache) {
8 @INC = grep ref, @INC; # weed out all paths except pars loader refs
9
10 while (my ($filename, $zip) = each %PAR::LibCache) {
11 for ($zip->memberNames) {
12 next unless /^\/root\/(.*)/;
13 $zip->extractMember ($_, "$ENV{PAR_TEMP}/$1")
14 unless -e "$ENV{PAR_TEMP}/$1";
15 }
16 }
17
18 unshift @INC, $ENV{PAR_TEMP};
19
20 if ($^O eq "MSWin32") {
21 $ENV{GTK_RC_FILES} = "$ENV{PAR_TEMP}/share/themes/MS-Windows/gtk-2.0/gtkrc";
22 }
23 }
24}
25
26# need to do it again because that pile of garbage called PAR nukes it before main
27unshift @INC, $ENV{PAR_TEMP};
5 28
6use Time::HiRes 'time'; 29use Time::HiRes 'time';
7use Event; 30use Event;
8 31
9use Crossfire; 32use Crossfire;
12use Compress::LZF; 35use Compress::LZF;
13 36
14use CFClient; 37use CFClient;
15use CFClient::UI; 38use CFClient::UI;
16use CFClient::MapWidget; 39use CFClient::MapWidget;
40
41$Event::DIED = sub {
42 CFClient::error $_[1];
43};
44
45#$SIG{__WARN__} = sub { Carp::cluck $_[0] };#d#
17 46
18our $VERSION = '0.1'; 47our $VERSION = '0.1';
19 48
20my $MAX_FPS = 60; 49my $MAX_FPS = 60;
21my $MIN_FPS = 5; # unused as of yet 50my $MIN_FPS = 5; # unused as of yet
36our @SDL_MODES; 65our @SDL_MODES;
37our $WIDTH; 66our $WIDTH;
38our $HEIGHT; 67our $HEIGHT;
39our $FULLSCREEN; 68our $FULLSCREEN;
40our $FONTSIZE; 69our $FONTSIZE;
70
71our $FONT_PROP;
72our $FONT_FIXED;
41 73
42our $MAP; 74our $MAP;
43our $MAPWIDGET; 75our $MAPWIDGET;
44our $BUTTONBAR; 76our $BUTTONBAR;
45our $LOGVIEW; 77our $LOGVIEW;
46our $CONSOLE; 78our $CONSOLE;
47our $METASERVER; 79our $METASERVER;
48 80
81our $FLOORBOX;
49our $GAUGES; 82our $GAUGES;
50our $STATWIDS; 83our $STATWIDS;
51 84
52our $SDL_ACTIVE; 85our $SDL_ACTIVE;
53our %SDL_CB; 86our %SDL_CB;
120 $mode_slider->emit (changed => $mode_slider->{range}[0]); 153 $mode_slider->emit (changed => $mode_slider->{range}[0]);
121 154
122 my $row = 1; 155 my $row = 1;
123 156
124 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Fullscreen"); 157 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Fullscreen");
125 $table->add (1, $row++, new CFClient::UI::CheckBox state => $CFG->{fullscreen}, connect_changed => sub { 158 $table->add (1, $row++, new CFClient::UI::CheckBox
159 state => $CFG->{fullscreen},
160 tooltip => "Bring the client into fullscreen mode",
161 connect_changed => sub {
126 my ($self, $value) = @_; 162 my ($self, $value) = @_;
127 $CFG->{fullscreen} = $value; 163 $CFG->{fullscreen} = $value;
164 }
128 }); 165 );
129 166
130 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Fast & Ugly"); 167 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Fast & Ugly");
131 $table->add (1, $row++, new CFClient::UI::CheckBox state => $CFG->{fast}, connect_changed => sub { 168 $table->add (1, $row++, new CFClient::UI::CheckBox
169 state => $CFG->{fast},
170 tooltip => "Lower the visual quality considerably to speed up rendering.",
171 connect_changed => sub {
132 my ($self, $value) = @_; 172 my ($self, $value) = @_;
133 $CFG->{fast} = $value; 173 $CFG->{fast} = $value;
174 }
134 }); 175 );
176
177 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Map Scale");
178 $table->add (1, $row++, new CFClient::UI::Slider
179 range => [$CFG->{map_scale}, 0.25, 2, 0.05],
180 tooltip => "Enlarge or shrink the displayed map",
181 connect_changed => sub {
182 my ($self, $value) = @_;
183 $CFG->{map_scale} = 0.05 * int $value / 0.05;
184 }
185 );
135 186
136 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Fog of War"); 187 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Fog of War");
137 $table->add (1, $row++, new CFClient::UI::CheckBox state => $CFG->{fow_enable}, connect_changed => sub { 188 $table->add (1, $row++, new CFClient::UI::CheckBox
189 state => $CFG->{fow_enable},
190 tooltip => "Fog-of-War marks areas that cannot be seen by the player",
191 connect_changed => sub {
138 my ($self, $value) = @_; 192 my ($self, $value) = @_;
139 $CFG->{fow_enable} = $value; 193 $CFG->{fow_enable} = $value;
194 }
140 }); 195 );
141 196
142 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "FoW Intensity"); 197 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "FoW Intensity");
143 $table->add (1, $row++, new CFClient::UI::Slider range => [$CFG->{fow_intensity}, 0, 1 + 0.001, 0.001], connect_changed => sub { 198 $table->add (1, $row++, new CFClient::UI::Slider
199 range => [$CFG->{fow_intensity}, 0, 1 + 0.001, 0.001],
200 tooltip => "The higher the intensity, the lighter the Fog-of-War color",
201 connect_changed => sub {
144 my ($self, $value) = @_; 202 my ($self, $value) = @_;
145 $CFG->{fow_intensity} = $value; 203 $CFG->{fow_intensity} = $value;
204 }
146 }); 205 );
147 206
148 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "FoW Smooth"); 207 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "FoW Smooth");
149 $table->add (1, $row++, new CFClient::UI::CheckBox state => $CFG->{fow_smooth}, connect_changed => sub { 208 $table->add (1, $row++, new CFClient::UI::CheckBox
209 state => $CFG->{fow_smooth},
210 tooltip => "Smooth the Fog-of-War a bit to make it more realistic",
211 connect_changed => sub {
150 my ($self, $value) = @_; 212 my ($self, $value) = @_;
151 $CFG->{fow_smooth} = $value; 213 $CFG->{fow_smooth} = $value;
152 status "Fog of War smoothing requires OpenGL 1.2 or higher" if $CFClient::GL_VERSION < 1.2; 214 status "Fog of War smoothing requires OpenGL 1.2 or higher" if $CFClient::GL_VERSION < 1.2;
215 }
153 }); 216 );
154 217
155 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "GUI Fontsize"); 218 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "GUI Fontsize");
156 $table->add (1, $row++, new CFClient::UI::Slider range => [$CFG->{gui_fontsize}, 0.7, 1.7, 0.1], connect_changed => sub { 219 $table->add (1, $row++, new CFClient::UI::Slider
220 range => [$CFG->{gui_fontsize}, 0.5, 2, 0.1],
221 tooltip => "The font size used by most GUI elements",
222 connect_changed => sub {
157 $CFG->{gui_fontsize} = 0.1 * int $_[1] * 10; 223 $CFG->{gui_fontsize} = 0.1 * int $_[1] * 10;
158# $FONTSIZE = int $HEIGHT / 40 * $CFG->{gui_fontsize}; 224# $FONTSIZE = int $HEIGHT / 40 * $CFG->{gui_fontsize};
225 }
159 }); 226 );
160 227
161 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Server Log Fontsize"); 228 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Server Log Fontsize");
162 $table->add (1, $row++, new CFClient::UI::Slider range => [$CFG->{log_fontsize}, 0.7, 1.7, 0.1], connect_changed => sub { 229 $table->add (1, $row++, new CFClient::UI::Slider
230 range => [$CFG->{log_fontsize}, 0.5, 2, 0.1],
231 tooltip => "The font size used by the server log window only",
232 connect_changed => sub {
163 $LOGVIEW->set_fontsize ($CFG->{log_fontsize} = 0.1 * int $_[1] * 10); 233 $LOGVIEW->set_fontsize ($CFG->{log_fontsize} = 0.1 * int $_[1] * 10);
234 }
164 }); 235 );
165 236
166 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Stats Fontsize"); 237 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Stats Fontsize");
167 $table->add (1, $row++, new CFClient::UI::Slider range => [$CFG->{stat_fontsize}, 0.7, 1.7, 0.1], connect_changed => sub { 238
239 $table->add (1, $row++, new CFClient::UI::Slider
240 range => [$CFG->{stat_fontsize}, 0.5, 2, 0.1],
241 tooltip => "The font size used by the statistics window only",
242 connect_changed => sub {
168 $CFG->{stat_fontsize} = 0.1 * int $_[1] * 10; 243 $CFG->{stat_fontsize} = 0.1 * int $_[1] * 10;
169 &set_stats_window_fontsize; 244 &set_stats_window_fontsize;
245 }
170 }); 246 );
171 247
172 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Gauge width"); 248 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Gauge size");
173 $table->add (1, $row++, new CFClient::UI::Slider range => [$CFG->{gauge_w_size}, 0.1, 0.5, 0.02], connect_changed => sub { 249 $table->add (1, $row++, new CFClient::UI::Slider
174 $CFG->{gauge_w_size} = $_[1]; 250 range => [$CFG->{gauge_size}, 0.2, 0.8, 0.02],
175 my $h = int ($HEIGHT * $CFG->{gauge_size}); 251 tooltip => "Adjust the size of the stats gauges at the bottom right",
176 my $w = int ($WIDTH * $CFG->{gauge_w_size}); 252 connect_changed => sub {
177 $GAUGES->{win}->set_size ($w, $h);
178 $GAUGES->{win}->{y} = $HEIGHT - $h;
179 $GAUGES->{win}->{x} = $WIDTH - $w;
180 $GAUGES->{win}->update;
181 });
182
183 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Gauge height");
184 $table->add (1, $row++, new CFClient::UI::Slider range => [$CFG->{gauge_size}, 0.2, 0.8, 0.02], connect_changed => sub {
185 $CFG->{gauge_size} = $_[1]; 253 $CFG->{gauge_size} = $_[1];
186 my $h = int ($HEIGHT * $CFG->{gauge_size}); 254 my $h = int $HEIGHT * $CFG->{gauge_size};
187 my $w = int ($WIDTH * $CFG->{gauge_w_size});
188 $GAUGES->{win}->set_size ($w, $h); 255 $GAUGES->{win}->set_size ($WIDTH, $h);
189 $GAUGES->{win}->{y} = $HEIGHT - $h; 256 $GAUGES->{win}->move (0, $HEIGHT - $h);
190 $GAUGES->{win}->{x} = $WIDTH - $w; 257 }
191 $GAUGES->{win}->update;
192 }); 258 );
193
194 259
195 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Gauge fontsize"); 260 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Gauge fontsize");
196 $table->add (1, $row++, new CFClient::UI::Slider range => [$CFG->{gauge_fontsize}, 0.7, 1.7, 0.1], connect_changed => sub { 261 $table->add (1, $row++, new CFClient::UI::Slider
262 range => [$CFG->{gauge_fontsize}, 0.5, 2.0, 0.1],
263 tooltip => "Adjusts the fontsize of the gauges at the bottom right",
264 connect_changed => sub {
197 $CFG->{gauge_fontsize} = 0.1 * int $_[1] * 10; 265 $CFG->{gauge_fontsize} = 0.1 * int $_[1] * 10;
198 &set_gauge_window_fontsize; 266 &set_gauge_window_fontsize;
199 $GAUGES->{win}->check_size; 267 }
200 $GAUGES->{win}->update;
201 }); 268 );
202 269
203 270 $table->add (1, $row++, new CFClient::UI::Button
204 271 expand => 1, align => 0, text => "Apply",
205 $table->add (1, $row++, new CFClient::UI::Button expand => 1, align => 0, text => "Apply", connect_activate => sub { 272 tooltip => "Apply the video settings",
273 connect_activate => sub {
206 video_shutdown (); 274 video_shutdown ();
207 video_init (); 275 video_init ();
276 }
208 }); 277 );
209 278
210 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Audio Enable"); 279 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Audio Enable");
211 $table->add (1, $row++, new CFClient::UI::CheckBox state => $CFG->{audio_enable}, connect_changed => sub { 280 $table->add (1, $row++, new CFClient::UI::CheckBox
281 state => $CFG->{audio_enable},
282 tooltip => "If enabled, sound effects and music will be played. If disabled, no audio will be used and the soundcard will not be opened.",
283 connect_changed => sub {
212 $CFG->{audio_enable} = $_[1]; 284 $CFG->{audio_enable} = $_[1];
285 }
213 }); 286 );
214# $table->add (0, 9, new CFClient::UI::Label valign => 0, align => 1, text => "Effects Volume"); 287# $table->add (0, 9, new CFClient::UI::Label valign => 0, align => 1, text => "Effects Volume");
215# $table->add (1, 8, new CFClient::UI::Slider range => [$CFG->{effects_volume}, 0, 128, 1], connect_changed => sub { 288# $table->add (1, 8, new CFClient::UI::Slider range => [$CFG->{effects_volume}, 0, 128, 1], connect_changed => sub {
216# $CFG->{effects_volume} = $_[1]; 289# $CFG->{effects_volume} = $_[1];
217# }); 290# });
218 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Background Music"); 291 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Background Music");
219 $table->add (1, $row++, my $hbox = new CFClient::UI::HBox); 292 $table->add (1, $row++, my $hbox = new CFClient::UI::HBox);
220 $hbox->add (new CFClient::UI::CheckBox expand => 1, state => $CFG->{bgm_enable}, connect_changed => sub { 293 $hbox->add (new CFClient::UI::CheckBox
294 expand => 1, state => $CFG->{bgm_enable},
295 tooltip => "Enable background music playing",
296 connect_changed => sub {
221 $CFG->{bgm_enable} = $_[1]; 297 $CFG->{bgm_enable} = $_[1];
298 }
222 }); 299 );
223 $hbox->add (new CFClient::UI::Slider expand => 1, range => [$CFG->{bgm_volume}, 0, 1, 0.1], connect_changed => sub { 300 $hbox->add (new CFClient::UI::Slider
301 expand => 1, range => [$CFG->{bgm_volume}, 0, 1, 0.1],
302 tooltip => "The volume of the background music",
303 connect_changed => sub {
224 $CFG->{bgm_volume} = $_[1]; 304 $CFG->{bgm_volume} = $_[1];
225 CFClient::MixMusic::volume $_[1] * 128; 305 CFClient::MixMusic::volume $_[1] * 128;
306 }
226 }); 307 );
227 308
228 $table->add (1, $row++, new CFClient::UI::Button expand => 1, align => 0, text => "Apply", connect_activate => sub { 309 $table->add (1, $row++, new CFClient::UI::Button
310 expand => 1, align => 0, text => "Apply",
311 tooltip => "Apply the audio settings",
312 connect_activate => sub {
229 audio_shutdown (); 313 audio_shutdown ();
230 audio_init (); 314 audio_init ();
315 }
231 }); 316 );
232 317
233 $dialog 318 $dialog
234} 319}
235 320
236sub set_stats_window_fontsize { 321sub set_stats_window_fontsize {
241 326
242sub set_gauge_window_fontsize { 327sub set_gauge_window_fontsize {
243 for (map { $GAUGES->{$_} } grep { $_ ne 'win' } keys %{$GAUGES}) { 328 for (map { $GAUGES->{$_} } grep { $_ ne 'win' } keys %{$GAUGES}) {
244 $_->set_fontsize ($::CFG->{gauge_fontsize}); 329 $_->set_fontsize ($::CFG->{gauge_fontsize});
245 } 330 }
331
332# local $GAUGES->{win}{parent};#d#
333# use PApp::Util; open D, ">:utf8", "d"; print D PApp::Util::dumpval $GAUGES->{win}; close D;
246} 334}
247 335
248sub make_gauge_window { 336sub make_gauge_window {
249 my $gh = int ($HEIGHT * $CFG->{gauge_size}); 337 my $gh = int ($HEIGHT * $CFG->{gauge_size});
250 my $gw = int ($WIDTH * $CFG->{gauge_w_size}); 338# my $gw = int ($WIDTH * $CFG->{gauge_w_size});
251 339
252 my $win = new CFClient::UI::Frame ( 340 my $win = new CFClient::UI::Frame (
253 y => $HEIGHT - $gh, x => $WIDTH - $gw, req_w => $gw, req_h => $gh 341 y => $HEIGHT - $gh, x => 0, user_w => $WIDTH, user_h => $gh
254 ); 342 );
255 $win->add (my $vb = new CFClient::UI::VBox); 343 $win->add (my $hbox = new CFClient::UI::HBox
256 344 children => [
257 $vb->add (my $hb = new CFClient::UI::HBox expand => 1); 345 (new CFClient::UI::HBox expand => 1),
346 ($FLOORBOX = new CFClient::UI::VBox),
347 (my $vbox = new CFClient::UI::VBox),
348 ],
349 );
350
351 $vbox->add (new CFClient::UI::HBox
352 expand => 1,
353 children => [
354 (new CFClient::UI::Empty expand => 1),
355 (my $hb = new CFClient::UI::HBox),
356 ],
357 );
358
258 $hb->add (my $hg = new CFClient::UI::Gauge type => 'hp', expand => 1); 359 $hb->add (my $hg = new CFClient::UI::Gauge type => 'hp',
360 tooltip => "Health points - depletes when you get wounded, refills when you heal or idle");
259 $hb->add (my $mg = new CFClient::UI::Gauge type => 'mana', expand => 1); 361 $hb->add (my $mg = new CFClient::UI::Gauge type => 'mana',
362 tooltip => "Spell points - deplete when you cast wizard spells, refills when you idle");
260 $hb->add (my $gg = new CFClient::UI::Gauge type => 'grace', expand => 1); 363 $hb->add (my $gg = new CFClient::UI::Gauge type => 'grace',
364 tooltip => "Grace points - deplete when you cast priest spells, refills when you pray");
261 $hb->add (my $fg = new CFClient::UI::Gauge type => 'food', expand => 1); 365 $hb->add (my $fg = new CFClient::UI::Gauge type => 'food',
366 tooltip => "Food - depletes with time, faster when you heal or build mana, refills when you eat healthy food");
367
262 $vb->add (my $exp = new CFClient::UI::Label valign => 0, align => -1, text => "XP:"); 368 $vbox->add (my $exp = new CFClient::UI::Label valign => 0, align => 1, can_hover => 1, can_events => 1,
263 $vb->add (my $lvl = new CFClient::UI::Label valign => 0, align => -1, text => "Lvl:"); 369 tooltip => "Experience points and level - increases when you kill monsters or successfully use skills");
264 $vb->add (my $rng = new CFClient::UI::Label valign => 0, align => -1, text => "Rng:"); 370 $vbox->add (my $rng = new CFClient::UI::Label valign => 0, align => 1, can_hover => 1, can_events => 1,
265 371 tooltip => "Ranged attack - how you attack when you press shift-cursor (spell, skill, weapon etc.)");
266 372
267 $GAUGES = { 373 $GAUGES = {
268 exp => $exp, lvl => $lvl, win => $win, range => $rng, 374 exp => $exp, win => $win, range => $rng,
269 food => $fg, mana => $mg, hp => $hg, grace => $gg 375 food => $fg, mana => $mg, hp => $hg, grace => $gg
270 }; 376 };
377
378 &set_gauge_window_fontsize;
379
271 $win 380 $win
272} 381}
273 382
274sub make_stats_window { 383sub make_stats_window {
275 my $tgw = new CFClient::UI::FancyFrame (x => $WIDTH * 2/5, y => 0, title => "Stats"); 384 my $tgw = new CFClient::UI::FancyFrame (x => $WIDTH * 2/5, y => 0, title => "Stats");
276 385
277 $tgw->add (my $vb = new CFClient::UI::VBox); 386 $tgw->add (my $vb = new CFClient::UI::VBox);
278 $vb->add (my $uhb = new CFClient::UI::HBox);
279 $uhb->add ($STATWIDS->{title} = new CFClient::UI::Label valign => 0, align => -1, text => "Title:", expand => 1); 387 $vb->add ($STATWIDS->{title} = new CFClient::UI::Label valign => 0, align => -1, text => "Title:", expand => 1);
280 $uhb->add ($STATWIDS->{map} = new CFClient::UI::Label valign => 0, align => -1, text => "Map:", expand => 1); 388 $vb->add ($STATWIDS->{map} = new CFClient::UI::Label valign => 0, align => -1, text => "Map:", expand => 1);
281 389
282 $vb->add (my $hb = new CFClient::UI::HBox expand => 1); 390 $vb->add (my $hb = new CFClient::UI::HBox expand => 1);
283 391
284 $hb->add (my $tbl = new CFClient::UI::Table expand => 1); 392 $hb->add (my $tbl = new CFClient::UI::Table expand => 1);
285 393
286 $tbl->add (0, 0, $STATWIDS->{st_str_lbl} = new CFClient::UI::Label valign => 0, align => +1, text => "Str"); 394 my $black = [0, 0, 0];
287 $tbl->add (0, 1, $STATWIDS->{st_dex_lbl} = new CFClient::UI::Label valign => 0, align => +1, text => "Dex");
288 $tbl->add (0, 2, $STATWIDS->{st_con_lbl} = new CFClient::UI::Label valign => 0, align => +1, text => "Con");
289 $tbl->add (0, 3, $STATWIDS->{st_int_lbl} = new CFClient::UI::Label valign => 0, align => +1, text => "Int");
290 $tbl->add (0, 4, $STATWIDS->{st_wis_lbl} = new CFClient::UI::Label valign => 0, align => +1, text => "Wis");
291 $tbl->add (0, 5, $STATWIDS->{st_pow_lbl} = new CFClient::UI::Label valign => 0, align => +1, text => "Pow");
292 $tbl->add (0, 6, $STATWIDS->{st_cha_lbl} = new CFClient::UI::Label valign => 0, align => +1, text => "Cha");
293 395
294 $tbl->add (1, 0, $STATWIDS->{st_str} = new CFClient::UI::Label valign => 0, align => +1, text => ""); 396 $tbl->add (0, 0, $STATWIDS->{st_str} = new CFClient::UI::Label valign => 0, align => +1, template => "30");
295 $tbl->add (1, 1, $STATWIDS->{st_dex} = new CFClient::UI::Label valign => 0, align => +1, text => ""); 397 $tbl->add (0, 1, $STATWIDS->{st_dex} = new CFClient::UI::Label valign => 0, align => +1, template => "30");
296 $tbl->add (1, 2, $STATWIDS->{st_con} = new CFClient::UI::Label valign => 0, align => +1, text => ""); 398 $tbl->add (0, 2, $STATWIDS->{st_con} = new CFClient::UI::Label valign => 0, align => +1, template => "30");
297 $tbl->add (1, 3, $STATWIDS->{st_int} = new CFClient::UI::Label valign => 0, align => +1, text => ""); 399 $tbl->add (0, 3, $STATWIDS->{st_int} = new CFClient::UI::Label valign => 0, align => +1, template => "30");
298 $tbl->add (1, 4, $STATWIDS->{st_wis} = new CFClient::UI::Label valign => 0, align => +1, text => ""); 400 $tbl->add (0, 4, $STATWIDS->{st_wis} = new CFClient::UI::Label valign => 0, align => +1, template => "30");
299 $tbl->add (1, 5, $STATWIDS->{st_pow} = new CFClient::UI::Label valign => 0, align => +1, text => ""); 401 $tbl->add (0, 5, $STATWIDS->{st_pow} = new CFClient::UI::Label valign => 0, align => +1, template => "30");
300 $tbl->add (1, 6, $STATWIDS->{st_cha} = new CFClient::UI::Label valign => 0, align => +1, text => ""); 402 $tbl->add (0, 6, $STATWIDS->{st_cha} = new CFClient::UI::Label valign => 0, align => +1, template => "30");
301 403
302 $tbl->add (2, 0, $STATWIDS->{st_wc_lbl} = new CFClient::UI::Label valign => 0, align => +1, text => "Wc");
303 $tbl->add (2, 1, $STATWIDS->{st_ac_lbl} = new CFClient::UI::Label valign => 0, align => +1, text => "Ac");
304 $tbl->add (2, 2, $STATWIDS->{st_dam_lbl} = new CFClient::UI::Label valign => 0, align => +1, text => "Dam");
305 $tbl->add (2, 3, $STATWIDS->{st_arm_lbl} = new CFClient::UI::Label valign => 0, align => +1, text => "Arm");
306 $tbl->add (2, 4, $STATWIDS->{st_spd_lbl} = new CFClient::UI::Label valign => 0, align => +1, text => "Sp"); 404 $tbl->add (1, 0, $STATWIDS->{st_str_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Str");
405 $tbl->add (1, 1, $STATWIDS->{st_dex_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Dex");
406 $tbl->add (1, 2, $STATWIDS->{st_con_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Con");
407 $tbl->add (1, 3, $STATWIDS->{st_int_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Int");
307 $tbl->add (2, 5, $STATWIDS->{st_wspd_lbl} = new CFClient::UI::Label valign => 0, align => +1, text => "WSp"); 408 $tbl->add (1, 4, $STATWIDS->{st_wis_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Wis");
409 $tbl->add (1, 5, $STATWIDS->{st_pow_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Pow");
410 $tbl->add (1, 6, $STATWIDS->{st_cha_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Cha");
308 411
309 $tbl->add (3, 0, $STATWIDS->{st_wc} = new CFClient::UI::Label valign => 0, align => +1, text => ""); 412 $tbl->add (2, 0, $STATWIDS->{st_wc} = new CFClient::UI::Label valign => 0, align => +1, template => "-120");
310 $tbl->add (3, 1, $STATWIDS->{st_ac} = new CFClient::UI::Label valign => 0, align => +1, text => ""); 413 $tbl->add (2, 1, $STATWIDS->{st_ac} = new CFClient::UI::Label valign => 0, align => +1, template => "-120");
311 $tbl->add (3, 2, $STATWIDS->{st_dam} = new CFClient::UI::Label valign => 0, align => +1, text => ""); 414 $tbl->add (2, 2, $STATWIDS->{st_dam} = new CFClient::UI::Label valign => 0, align => +1, template => "120");
312 $tbl->add (3, 3, $STATWIDS->{st_arm} = new CFClient::UI::Label valign => 0, align => +1, text => ""); 415 $tbl->add (2, 3, $STATWIDS->{st_arm} = new CFClient::UI::Label valign => 0, align => +1, template => "120");
313 $tbl->add (3, 4, $STATWIDS->{st_spd} = new CFClient::UI::Label valign => 0, align => +1, text => ""); 416 $tbl->add (2, 4, $STATWIDS->{st_spd} = new CFClient::UI::Label valign => 0, align => +1, template => "10.54");
314 $tbl->add (3, 5, $STATWIDS->{st_wspd} = new CFClient::UI::Label valign => 0, align => +1, text => ""); 417 $tbl->add (2, 5, $STATWIDS->{st_wspd} = new CFClient::UI::Label valign => 0, align => +1, template => "9");
418
419 $tbl->add (3, 0, $STATWIDS->{st_wc_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Wc");
420 $tbl->add (3, 1, $STATWIDS->{st_ac_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Ac");
421 $tbl->add (3, 2, $STATWIDS->{st_dam_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Dam");
422 $tbl->add (3, 3, $STATWIDS->{st_arm_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Arm");
423 $tbl->add (3, 4, $STATWIDS->{st_spd_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Sp");
424 $tbl->add (3, 5, $STATWIDS->{st_wspd_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "WSp");
315 425
316 $hb->add (my $tbl2 = new CFClient::UI::Table expand => 1); 426 $hb->add (my $tbl2 = new CFClient::UI::Table expand => 1);
317 427
318 my $row = 0; 428 my $row = 0;
319 my $col = 0; 429 my $col = 0;
320 430
431 my %resist_names = (
432 slow => "Slow",
433 holyw => "Holy Word",
434 conf => "Confusion",
435 fire => "Fire",
436 depl => "Depletion",
437 magic => "Magic",
438 drain => "Draining",
439 acid => "Acid",
440 pois => "Poison",
441 para => "Paralysation",
442 deat => "Death",
443 phys => "Physical",
444 blind => "Blind",
445 fear => "Fear",
446 tund => "Turn undead",
447 elec => "Electricity",
448 cold => "Cold",
449 ghit => "Ghost hit",
450 );
321 for (qw/slow holyw conf fire depl magic 451 for (qw/slow holyw conf fire depl magic
322 drain acid pois para deat phys 452 drain acid pois para deat phys
323 blind fear tund elec cold ghit/) 453 blind fear tund elec cold ghit/)
324 { 454 {
325 $tbl2->add ($col , $row, 455 $tbl2->add ($col, $row,
326 $STATWIDS->{"res_$_"} = 456 $STATWIDS->{"res_$_"} =
327 new CFClient::UI::Label text => "0", align => +1, valign => 0 457 new CFClient::UI::Label
458 template => "-100%",
459 align => +1,
460 valign => 0,
461 tooltip => $resist_names{$_}
328 ); 462 );
329 $tbl2->add ($col + 1, $row, new CFClient::UI::Image image => "ui/resist/resist_$_.png"); 463 $tbl2->add ($col + 1, $row, new CFClient::UI::Image
464 can_hover => 1,
465 can_events => 1,
466 image => "ui/resist/resist_$_.png",
467 tooltip => $resist_names{$_}
468 );
330 469
331 $row++; 470 $row++;
332 if ($row % 6 == 0) { 471 if ($row % 6 == 0) {
333 $col += 2; 472 $col += 2;
334 $row = 0; 473 $row = 0;
339 update_stats_window ({}); 478 update_stats_window ({});
340 479
341 $tgw 480 $tgw
342} 481}
343 482
483sub formsep {
484 reverse join ",", grep length, split /(...)/, reverse $_[0] * 1
485}
486
344sub update_stats_window { 487sub update_stats_window {
345 my ($stats) = @_; 488 my ($stats) = @_;
346 489
347 # i love text protocols!!! 490 # i love text protocols!!!
348 my $hp = $stats->{1} * 1; 491 my $hp = $stats->{Crossfire::Protocol::CS_STAT_HP} * 1;
349 my $hp_m = $stats->{2} * 1; 492 my $hp_m = $stats->{Crossfire::Protocol::CS_STAT_MAXHP} * 1;
350 my $sp = $stats->{3} * 1; 493 my $sp = $stats->{Crossfire::Protocol::CS_STAT_SP} * 1;
351 my $sp_m = $stats->{4} * 1; 494 my $sp_m = $stats->{Crossfire::Protocol::CS_STAT_MAXSP} * 1;
352 my $fo = $stats->{18} * 1; 495 my $fo = $stats->{Crossfire::Protocol::CS_STAT_FOOD} * 1;
353 my $fo_m = 999; 496 my $fo_m = 999;
354 my $gr = $stats->{23} * 1; 497 my $gr = $stats->{Crossfire::Protocol::CS_STAT_GRACE} * 1;
355 my $gr_m = $stats->{24} * 1; 498 my $gr_m = $stats->{Crossfire::Protocol::CS_STAT_MAXGRACE} * 1;
356 499
357 $GAUGES->{hp} ->set_value ($hp, $hp_m); 500 $GAUGES->{hp} ->set_value ($hp, $hp_m);
358 $GAUGES->{mana} ->set_value ($sp, $sp_m); 501 $GAUGES->{mana} ->set_value ($sp, $sp_m);
359 $GAUGES->{food} ->set_value ($fo, $fo_m); 502 $GAUGES->{food} ->set_value ($fo, $fo_m);
360 $GAUGES->{grace} ->set_value ($gr, $gr_m); 503 $GAUGES->{grace} ->set_value ($gr, $gr_m);
361 $GAUGES->{exp} ->set_text ("XP: " . ($stats->{11} || $stats->{28})); 504 $GAUGES->{exp} ->set_text ("Exp: " . (formsep $stats->{Crossfire::Protocol::CS_STAT_EXP64})
362 my $rng = $stats->{20}; 505 . " (lvl " . ($stats->{Crossfire::Protocol::CS_STAT_LEVEL} * 1) . ")");
506 my $rng = $stats->{Crossfire::Protocol::CS_STAT_RANGE};
363 $rng =~ s/^Range: //; # thank you so much dear server 507 $rng =~ s/^Range: //; # thank you so much dear server
364 $GAUGES->{range} ->set_text ("Rng: " . $rng); 508 $GAUGES->{range} ->set_text ("Rng: " . $rng);
365 $GAUGES->{lvl} ->set_text ("LVL: " . $stats->{12}); 509 my $title = $stats->{Crossfire::Protocol::CS_STAT_TITLE};
510 $title =~ s/^Player: //;
366 $STATWIDS->{title} ->set_text ("Title: " . $stats->{21}); 511 $STATWIDS->{title} ->set_text ("Title: " . $title);
367 512
368 if (0) { # this code can vanish, just wanted to preserver it for a checkin
369 $STATWIDS->{st_str} ->set_text (sprintf "S%d", $stats->{5});
370 $STATWIDS->{st_dex} ->set_text (sprintf "D%d", $stats->{8});
371 $STATWIDS->{st_con} ->set_text (sprintf "Co%d", $stats->{9});
372 $STATWIDS->{st_int} ->set_text (sprintf "I%d", $stats->{6});
373 $STATWIDS->{st_wis} ->set_text (sprintf "W%d", $stats->{7});
374 $STATWIDS->{st_pow} ->set_text (sprintf "P%d", $stats->{22});
375 $STATWIDS->{st_cha} ->set_text (sprintf "Ch%d", $stats->{10});
376 $STATWIDS->{st_wc} ->set_text (sprintf "Wc%d", $stats->{13});
377 $STATWIDS->{st_ac} ->set_text (sprintf "Ac%d", $stats->{14});
378 $STATWIDS->{st_dam} ->set_text (sprintf "Dam%d", $stats->{15});
379 $STATWIDS->{st_arm} ->set_text (sprintf "Arm%d", $stats->{16});
380 $STATWIDS->{st_spd} ->set_text (sprintf "Sp%.1f", $stats->{17});
381 $STATWIDS->{st_wspd}->set_text (sprintf "WSp%.1f", $stats->{19});
382 } else {
383 $STATWIDS->{st_str} ->set_text (sprintf "%d", $stats->{5}); 513 $STATWIDS->{st_str} ->set_text (sprintf "%d", $stats->{5});
384 $STATWIDS->{st_dex} ->set_text (sprintf "%d", $stats->{8}); 514 $STATWIDS->{st_dex} ->set_text (sprintf "%d", $stats->{8});
385 $STATWIDS->{st_con} ->set_text (sprintf "%d", $stats->{9}); 515 $STATWIDS->{st_con} ->set_text (sprintf "%d", $stats->{9});
386 $STATWIDS->{st_int} ->set_text (sprintf "%d", $stats->{6}); 516 $STATWIDS->{st_int} ->set_text (sprintf "%d", $stats->{6});
387 $STATWIDS->{st_wis} ->set_text (sprintf "%d", $stats->{7}); 517 $STATWIDS->{st_wis} ->set_text (sprintf "%d", $stats->{7});
388 $STATWIDS->{st_pow} ->set_text (sprintf "%d", $stats->{22}); 518 $STATWIDS->{st_pow} ->set_text (sprintf "%d", $stats->{22});
389 $STATWIDS->{st_cha} ->set_text (sprintf "%d", $stats->{10}); 519 $STATWIDS->{st_cha} ->set_text (sprintf "%d", $stats->{10});
390 $STATWIDS->{st_wc} ->set_text (sprintf "%d", $stats->{13}); 520 $STATWIDS->{st_wc} ->set_text (sprintf "%d", $stats->{13});
391 $STATWIDS->{st_ac} ->set_text (sprintf "%d", $stats->{14}); 521 $STATWIDS->{st_ac} ->set_text (sprintf "%d", $stats->{14});
392 $STATWIDS->{st_dam} ->set_text (sprintf "%d", $stats->{15}); 522 $STATWIDS->{st_dam} ->set_text (sprintf "%d", $stats->{15});
393 $STATWIDS->{st_arm} ->set_text (sprintf "%d", $stats->{16}); 523 $STATWIDS->{st_arm} ->set_text (sprintf "%d", $stats->{16});
394 $STATWIDS->{st_spd} ->set_text (sprintf "%.1f", $stats->{17}); 524 $STATWIDS->{st_spd} ->set_text (sprintf "%.1f", $stats->{Crossfire::Protocol::CS_STAT_SPEED});
395 $STATWIDS->{st_wspd}->set_text (sprintf "%.1f", $stats->{19}); 525 $STATWIDS->{st_wspd}->set_text (sprintf "%.1f", $stats->{Crossfire::Protocol::CS_STAT_WEAP_SP});
396 }
397 526
398 my %tbl = ( 527 my %tbl = (
399 phys => 100, 528 phys => 100,
400 magic => 101, 529 magic => 101,
401 fire => 102, 530 fire => 102,
408 pois => 109, 537 pois => 109,
409 slow => 110, 538 slow => 110,
410 para => 111, 539 para => 111,
411 tund => 112, 540 tund => 112,
412 fear => 113, 541 fear => 113,
542 depl => 113,
413 deat => 115, 543 deat => 115,
414 holyw => 116, 544 holyw => 116,
415 blind => 117 545 blind => 117
416 ); 546 );
417 547
432} 562}
433 563
434sub update_metaserver { 564sub update_metaserver {
435 my ($HOST) = @_; 565 my ($HOST) = @_;
436 566
437 status "fetching metaserver list..."; 567 my $table = $METASERVER->{table};
568 $table->clear;
569 $table->add (0, 0, my $label = new CFClient::UI::Label max_w => $WIDTH * 0.8, text => "fetching metaserver list...");
438 570
439 my $buf; 571 my $buf;
440 572
441 my $fh = new IO::Socket::INET PeerHost => $META_SERVER, Blocking => 0; 573 my $fh = new IO::Socket::INET PeerHost => $META_SERVER, Blocking => 0;
574
575 unless ($fh) {
576 $label->set_text ("unable to contact metaserver: $!");
577 return;
578 }
442 579
443 Event->io (fd => $fh, poll => 'r', cb => sub { 580 Event->io (fd => $fh, poll => 'r', cb => sub {
444 my $res = sysread $fh, $buf, 8192, length $buf; 581 my $res = sysread $fh, $buf, 8192, length $buf;
445 582
446 if (!defined $res) { 583 if (!defined $res) {
447 $_[0]->w->cancel; 584 $_[0]->w->cancel;
448 status "metaserver: $!"; 585 $label->set_text ("error while retrieving server list: $!");
449 } elsif ($res == 0) { 586 } elsif ($res == 0) {
450 $_[0]->w->cancel; 587 $_[0]->w->cancel;
451 status "server list retrieved"; 588 status "server list retrieved";
452 589
453 my $table = $METASERVER->{table}; 590 utf8::decode $buf if utf8::valid $buf;
454 591
455 $table->clear; 592 $table->clear;
456 593
457 my @col = qw(Use #Users Host Uptime Version Description); 594 my @col = qw(Use #Users Host Uptime Version Description);
458 $table->add ($_, 0, new CFClient::UI::Label align => 0, fg => [1, 1, 0], text => $col[$_]) 595 $table->add ($_, 0, new CFClient::UI::Label align => 0, fg => [1, 1, 0], text => $col[$_])
482 $m = [$users, $host, $uptime, $version, $desc]; 619 $m = [$users, $host, $uptime, $version, $desc];
483 620
484 $y++; 621 $y++;
485 622
486 $table->add (0, $y, new CFClient::UI::VBox children => [ 623 $table->add (0, $y, new CFClient::UI::VBox children => [
487 (new CFClient::UI::Button text => " ", connect_activate => sub { 624 (new CFClient::UI::Button text => "Use", connect_activate => sub {
488 $HOST->set_text ($CFG->{host} = $host); 625 $HOST->set_text ($CFG->{host} = $host);
489 }), 626 }),
490 (new CFClient::UI::Empty expand => 1), 627 (new CFClient::UI::Empty expand => 1),
491 ]); 628 ]);
492 629
506 $table->add (0, 2, new CFClient::UI::Label valign => 0, align => 1, text => "Host:Port"); 643 $table->add (0, 2, new CFClient::UI::Label valign => 0, align => 1, text => "Host:Port");
507 644
508 { 645 {
509 $table->add (1, 2, my $vbox = new CFClient::UI::VBox); 646 $table->add (1, 2, my $vbox = new CFClient::UI::VBox);
510 647
511 $vbox->add (my $HOST = new CFClient::UI::Entry expand => 1, text => $CFG->{host}, connect_changed => sub { 648 $vbox->add (
649 my $HOST = new CFClient::UI::Entry
650 expand => 1,
651 text => $CFG->{host},
652 tooltip => "The hostname or ip address of the Crossfire(+) server to connect to",
653 connect_changed => sub {
654 my ($self, $value) = @_;
655 $CFG->{host} = $value;
656 }
657 );
658
659 $METASERVER = metaserver_dialog;
660
661 $vbox->add (new CFClient::UI::Flopper
662 expand => 1,
663 text => "Metaserver",
664 other => $METASERVER,
665 tooltip => "Show a list of avaible crossfire servers",
666 connect_open => sub {
667 update_metaserver $HOST;
668 }
669 );
670 }
671
672 $table->add (0, 4, new CFClient::UI::Label valign => 0, align => 1, text => "Username");
673 $table->add (1, 4, new CFClient::UI::Entry
674 text => $CFG->{user},
675 tooltip => "The name of your character on the server",
676 connect_changed => sub {
512 my ($self, $value) = @_; 677 my ($self, $value) = @_;
513 $CFG->{host} = $value;
514 });
515
516 $METASERVER = metaserver_dialog;
517
518 $vbox->add (new CFClient::UI::Flopper expand => 1, text => "Metaserver", other => $METASERVER, connect_open => sub {
519 update_metaserver $HOST;
520 });
521 }
522
523 $table->add (0, 4, new CFClient::UI::Label valign => 0, align => 1, text => "Username");
524 $table->add (1, 4, new CFClient::UI::Entry text => $CFG->{user}, connect_changed => sub {
525 my ($self, $value) = @_;
526 $CFG->{user} = $value; 678 $CFG->{user} = $value;
679 }
527 }); 680 );
528 681
529 $table->add (0, 5, new CFClient::UI::Label valign => 0, align => 1, text => "Password"); 682 $table->add (0, 5, new CFClient::UI::Label valign => 0, align => 1, text => "Password");
530 $table->add (1, 5, new CFClient::UI::Entry text => $CFG->{password}, hidden => 1, connect_changed => sub { 683 $table->add (1, 5, new CFClient::UI::Entry
684 text => $CFG->{password},
685 hidden => 1,
686 tooltip => "The password for your character",
687 connect_changed => sub {
531 my ($self, $value) = @_; 688 my ($self, $value) = @_;
532 $CFG->{password} = $value; 689 $CFG->{password} = $value;
690 }
533 }); 691 );
534 692
535 $table->add (0, 6, new CFClient::UI::Label valign => 0, align => 1, text => "Def. say cmd"); 693 $table->add (0, 6, new CFClient::UI::Label valign => 0, align => 1, text => "Def. say cmd");
536 $table->add (1, 6, my $saycmd = new CFClient::UI::Entry text => $CFG->{say_command}, connect_changed => sub { 694 $table->add (1, 6, my $saycmd = new CFClient::UI::Entry
695 text => $CFG->{say_command},
696 tooltip => "This is the command that will be used if you write a line in the message window entry. "
697 ."Usually you want to enter something like 'say' or 'shout' or 'gsay' here. "
698 ."But you could also set it to 'tell &lt;playername&gt;' to only chat with that user.",
699 connect_changed => sub {
537 my ($self, $value) = @_; 700 my ($self, $value) = @_;
538 $CFG->{say_command} = $value; 701 $CFG->{say_command} = $value;
702 }
539 }); 703 );
540 704
541 $table->add (0, 7, new CFClient::UI::Label valign => 0, align => 1, text => "Map Size"); 705 $table->add (0, 7, new CFClient::UI::Label valign => 0, align => 1, text => "Map Size");
542 $table->add (1, 7, new CFClient::UI::Slider 706 $table->add (1, 7, new CFClient::UI::Slider
543 req_w => 100, 707 req_w => 100,
544 range => [$CFG->{mapsize}, 10, 100 + 1, 1], 708 range => [$CFG->{mapsize}, 10, 100 + 1, 1],
709 tooltip => "This is the size of the portion of the map update the server sends you. "
710 ."If you set this to a high value you will be able to see further for example.",
545 connect_changed => sub { 711 connect_changed => sub {
546 my ($self, $value) = @_; 712 my ($self, $value) = @_;
547 713
548 $CFG->{mapsize} = $self->{range}[0] = $value = int $value; 714 $CFG->{mapsize} = $self->{range}[0] = $value = int $value;
549 }, 715 },
565 user_h => int $::HEIGHT / 5, 731 user_h => int $::HEIGHT / 5,
566 child => (my $vbox = new CFClient::UI::VBox); 732 child => (my $vbox = new CFClient::UI::VBox);
567 733
568 $vbox->add ($LOGVIEW = new CFClient::UI::TextView 734 $vbox->add ($LOGVIEW = new CFClient::UI::TextView
569 expand => 1, 735 expand => 1,
736 font => $FONT_FIXED,
570 fontsize => $::CFG->{log_fontsize}, 737 fontsize => $::CFG->{log_fontsize},
571 ); 738 );
572 739
573 $vbox->add (my $input = new CFClient::UI::Entry 740 $vbox->add (my $input = new CFClient::UI::Entry
574 connect_focus_in => sub { 741 connect_focus_in => sub {
668 835
669 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Client Setup", other => client_setup); 836 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Client Setup", other => client_setup);
670 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Server Setup", other => server_setup); 837 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Server Setup", other => server_setup);
671 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Message Window", other => message_window); 838 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Message Window", other => message_window);
672 839
840 $CFClient::UI::ROOT->add (make_gauge_window); # 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
841 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Stats Window", other => make_stats_window);
842
673 $BUTTONBAR->add (new CFClient::UI::Button text => "Save Config", connect_activate => sub { 843 $BUTTONBAR->add (new CFClient::UI::Button text => "Save Config", connect_activate => sub {
674 CFClient::write_cfg "$Crossfire::VARDIR/pclientrc"; 844 CFClient::write_cfg "$Crossfire::VARDIR/pclientrc";
675 status "Configuration Saved"; 845 status "Configuration Saved";
676 }); 846 });
677 847
678 $CFClient::UI::ROOT->add (make_gauge_window); # 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
679 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Stats Window", other => make_stats_window);
680
681 $BUTTONBAR->{children}[1]->emit ("activate"); # pop up server setup 848 $BUTTONBAR->{children}[1]->emit ("activate"); # pop up server setup
682
683
684} 849}
685 850
686sub video_shutdown { 851sub video_shutdown {
687 $CFClient::UI::ROOT->{children} = []; 852 $CFClient::UI::ROOT->{children} = [];
853 undef $CFClient::UI::GRAB;
854 undef $CFClient::UI::HOVER;
688 undef $SDL_ACTIVE; 855 undef $SDL_ACTIVE;
689} 856}
690 857
691my @bgmusic = qw(game1.ogg game2.ogg game3.ogg game5.ogg game6.ogg ross1.ogg ross2.ogg ross3.ogg ross4.ogg ross5.ogg); #d# 858my @bgmusic = qw(game1.ogg game2.ogg game3.ogg game5.ogg game6.ogg ross1.ogg ross2.ogg ross3.ogg ross4.ogg ross5.ogg); #d#
692my $bgmusic;#TODO#hack#d# 859my $bgmusic;#TODO#hack#d#
973 } 1140 }
974 1141
975gotid: 1142gotid:
976 $face->{id} = $id; 1143 $face->{id} = $id;
977 $MAP->set_face ($facenum => $id); 1144 $MAP->set_face ($facenum => $id);
1145 $self->{faceid}[$facenum] = $id;#d#
978 $TILECACHE->get ($id) 1146 $TILECACHE->get ($id)
979} 1147}
980 1148
981sub conn::face_update { 1149sub conn::face_update {
982 my ($self, $facenum, $face) = @_; 1150 my ($self, $facenum, $face) = @_;
990 my ($self, $id, $data) = @_; 1158 my ($self, $id, $data) = @_;
991 1159
992 $self->{texture}[$id] ||= do { 1160 $self->{texture}[$id] ||= do {
993 my $tex = 1161 my $tex =
994 new_from_image CFClient::Texture 1162 new_from_image CFClient::Texture
995 $data, minify => 1; 1163 $data, minify => 1, mipmap => 1;
996 1164
997 $MAP->set_texture ($id, @$tex{qw(name w h s t)}, @{$tex->{minified}}); 1165 $MAP->set_texture ($id, @$tex{qw(name w h s t)}, @{$tex->{minified}});
998 $MAPWIDGET->update; 1166 $MAPWIDGET->update;
999 1167
1000 $tex 1168 $tex
1012 1180
1013 $chunk->play; 1181 $chunk->play;
1014# warn "sound $x,$y,$soundnum,$type\n";#d# 1182# warn "sound $x,$y,$soundnum,$type\n";#d#
1015} 1183}
1016 1184
1185my $LAST_QUERY; # server is stupid, stupid, stupid
1186
1017sub conn::query { 1187sub conn::query {
1018 my ($self, $flags, $prompt) = @_; 1188 my ($self, $flags, $prompt) = @_;
1019 1189
1020 #TODO, display dialog with relevant information 1190 $prompt = $LAST_QUERY unless length $prompt;
1021 warn "<<<<QUERY:$flags:$prompt>>>\n";#d# 1191 $LAST_QUERY = $prompt;
1192
1193 my $dialog = new CFClient::UI::FancyFrame
1194 title => "Query",
1195 child => my $vbox = new CFClient::UI::VBox;
1196
1197 $vbox->add (new CFClient::UI::Label
1198 max_w => $::WIDTH * 0.4,
1199 text => $prompt);
1200
1201 if ($flags & Crossfire::Protocol::CS_QUERY_YESNO) {
1202 $vbox->add (my $hbox = new CFClient::HBox);
1203 $hbox->add (new CFClient::Button
1204 text => "No",
1205 connect_activate => sub {
1206 $self->send ("reply n");
1207 $dialog->destroy;
1208 $MAPWIDGET->focus_in;
1209 }
1210 );
1211 $hbox->add (new CFClient::Button
1212 text => "Yes",
1213 connect_activate => sub {
1214 $self->send ("reply y");
1215 $dialog->destroy;
1216 $MAPWIDGET->focus_in;
1217 },
1218 );
1219
1220 $dialog->focus_in;
1221
1222 } elsif ($flags & Crossfire::Protocol::CS_QUERY_SINGLECHAR) {
1223 $dialog->{tooltip} = "Press a key (click on the entry to make sure it has keyboard focus)";
1224 $vbox->add (my $entry = new CFClient::UI::Entry
1225 connect_changed => sub {
1226 $self->send ("reply $_[1]");
1227 $dialog->destroy;
1228 $MAPWIDGET->focus_in;
1229 },
1230 );
1231
1232 $entry->focus_in;
1233
1234 } else {
1235 $dialog->{tooltip} = "Enter the reply and press return (click on the entry to make sure it has keyboard focus)";
1236
1237 $vbox->add (my $entry = new CFClient::UI::Entry
1238 $flags & Crossfire::Protocol::CS_QUERY_HIDEINPUT ? (hiddenchar => "*") : (),
1239 connect_activate => sub {
1240 $self->send ("reply $_[1]");
1241 $dialog->destroy;
1242 $MAPWIDGET->focus_in;
1243 },
1244 );
1245
1246 $entry->focus_in;
1247 }
1248
1249 $dialog->show;
1022} 1250}
1023 1251
1024sub conn::drawinfo { 1252sub conn::drawinfo {
1025 my ($self, $color, $text) = @_; 1253 my ($self, $color, $text) = @_;
1026 1254
1044} 1272}
1045 1273
1046sub conn::spell_add { 1274sub conn::spell_add {
1047 my ($self, $spell) = @_; 1275 my ($self, $spell) = @_;
1048 1276
1277 # TODO
1278 # create a widget dynamically, using spell face (CF::Protocol downloads them)
1049 $MAPWIDGET->add_command ("invoke $spell->{name}", $spell->{message}, sub { 1279 $MAPWIDGET->add_command ("invoke $spell->{name}", $spell->{message});
1050 });
1051 $MAPWIDGET->add_command ("cast $spell->{name}", $spell->{message}, sub { 1280 $MAPWIDGET->add_command ("cast $spell->{name}", $spell->{message});
1052 });
1053} 1281}
1054 1282
1055sub conn::spell_delete { 1283sub conn::spell_delete {
1056 my ($self, $spell) = @_; 1284 my ($self, $spell) = @_;
1057} 1285}
1058 1286
1059sub conn::addme_success { 1287sub conn::addme_success {
1060 my ($self) = @_; 1288 my ($self) = @_;
1061 1289
1062 for my $skill (values %{$self->{skill_info}}) { 1290 for my $skill (values %{$self->{skill_info}}) {
1063 $MAPWIDGET->add_command ("ready_skill $skill", "", sub { 1291 $MAPWIDGET->add_command ("ready_skill $skill", "Ready the skill '$skill'");
1064 }); 1292 $MAPWIDGET->add_command ("use_skill $skill", "Immediately use the skill '$skill'");
1065 $MAPWIDGET->add_command ("use_skill $skill", "", sub {
1066 });
1067 } 1293 }
1294}
1295
1296sub update_floorbox {
1297 $CFClient::UI::ROOT->on_refresh ($FLOORBOX => sub {
1298 $FLOORBOX->clear;
1299 $FLOORBOX->add (new CFClient::UI::Empty expand => 1);
1300
1301 my @items = values %{ $CONN->{container}{0} };
1302
1303 # we basically have to use the same sorting as everybody else
1304 @items = sort { $a->{type} <=> $b->{type} } @items;
1305
1306 for my $item (reverse @items) {
1307 my $desc = $item->{nrof} < 2
1308 ? $item->{name}
1309 : "$item->{nrof} $item->{name_pl}";
1310 # todo: animation widget, face widget, weight(?) etc.
1311 $FLOORBOX->add (my $hbox = new CFClient::UI::HBox
1312 tooltip => (CFClient::UI::Label->escape ($desc)
1313 . "\n<small>leftclick - pick up\nmiddle click - apply\nrightclick - menu</small>"),
1314 can_hover => 1,
1315 can_events => 1,
1316 connect_button_down => sub {
1317 my ($self, $ev, $x, $y) = @_;
1318
1319 # todo: maybe put examine on 1? but should just be a tooltip :(
1320 if ($ev->{button} == 1) {
1321 $CONN->send ("move $CONN->{player}{tag} $item->{tag} 0");
1322 } elsif ($ev->{button} == 2) {
1323 $CONN->send ("apply $item->{tag}");
1324 } elsif ($ev->{button} == 3) {
1325 # examine, lock, mark, maybe other things
1326 warn "MENU not implemented yet\n";
1327 }
1328
1329 1
1330 },
1331 );
1332
1333 $hbox->add (new CFClient::UI::Face
1334 can_events => 0,
1335 face => $item->{face},
1336 anim => $item->{anim},
1337 animspeed => $item->{animspeed},
1338 );
1339
1340 $hbox->add (new CFClient::UI::Label
1341 can_events => 0,
1342 text => $desc,
1343 );
1344 }
1345 });
1346 refresh;
1347}
1348
1349sub conn::container_add {
1350 my ($self, $id, $items) = @_;
1351
1352 update_floorbox if $id == 0;
1353 # $self-<{player}{tag} => player inv
1354 #use PApp::Util; warn PApp::Util::dumpval $self->{container}{$self->{player}{tag}};
1355}
1356
1357sub conn::container_clear {
1358 my ($self, $id) = @_;
1359
1360 update_floorbox if $id == 0;
1361# use PApp::Util; warn PApp::Util::dumpval $self->{container}{0};
1362}
1363
1364sub conn::item_delete {
1365 my ($self, @items) = @_;
1366
1367 for (@items) {
1368 update_floorbox if $_->{container} == 0;
1369 }
1370}
1371
1372sub conn::item_update {
1373 my ($self, $item) = @_;
1374
1375 update_floorbox if $item->{container} == 0;
1068} 1376}
1069 1377
1070%SDL_CB = ( 1378%SDL_CB = (
1071 CFClient::SDL_QUIT => sub { 1379 CFClient::SDL_QUIT => sub {
1072 Event::unloop -1; 1380 Event::unloop -1;
1107 sdl_mode => 0, 1415 sdl_mode => 0,
1108 width => 640, 1416 width => 640,
1109 height => 480, 1417 height => 480,
1110 fullscreen => 0, 1418 fullscreen => 0,
1111 fast => 0, 1419 fast => 0,
1420 map_scale => 0.5,
1112 fow_enable => 1, 1421 fow_enable => 1,
1113 fow_intensity => 0.45, 1422 fow_intensity => 0.45,
1114 fow_smooth => 0, 1423 fow_smooth => 0,
1115 gui_fontsize => 1, 1424 gui_fontsize => 1,
1116 log_fontsize => 1, 1425 log_fontsize => 1,
1117 gauge_fontsize => 1, 1426 gauge_fontsize => 1,
1118 gauge_size => 0.35, 1427 gauge_size => 0.35,
1119 gauge_w_size => 0.14,
1120 stat_fontsize => 1, 1428 stat_fontsize => 1,
1121 mapsize => 100, 1429 mapsize => 100,
1122 host => "crossfire.schmorp.de", 1430 host => "crossfire.schmorp.de",
1123 say_command => 'say', 1431 say_command => 'say',
1124 audio_enable => 1, 1432 audio_enable => 1,
1139@SDL_MODES or CFClient::fatal "Unable to find a usable video mode\n(hardware accelerated opengl fullscreen)"; 1447@SDL_MODES or CFClient::fatal "Unable to find a usable video mode\n(hardware accelerated opengl fullscreen)";
1140 1448
1141$CFG->{sdl_mode} = 0 if $CFG->{sdl_mode} > @SDL_MODES; 1449$CFG->{sdl_mode} = 0 if $CFG->{sdl_mode} > @SDL_MODES;
1142 1450
1143{ 1451{
1144 my @fonts = map CFClient::find_rcfile $_, qw(uifont.ttf uifontb.ttf uifonti.ttf uifontbi.ttf); 1452 my @fonts = map CFClient::find_rcfile "fonts/$_", qw(
1453 DejaVuSans.ttf
1454 DejaVuSansMono.ttf
1455 DejaVuSans-Bold.ttf
1456 DejaVuSansMono-Bold.ttf
1457 DejaVuSans-Oblique.ttf
1458 DejaVuSansMono-Oblique.ttf
1459 DejaVuSans-BoldOblique.ttf
1460 DejaVuSansMono-BoldOblique.ttf
1461 );
1145 1462
1146 CFClient::add_font $_ for @fonts; 1463 CFClient::add_font $_ for @fonts;
1147 CFClient::set_font $fonts[0]; 1464
1465 $FONT_PROP = new_from_file CFClient::Font $fonts[0];
1466 $FONT_FIXED = new_from_file CFClient::Font $fonts[1];
1467
1468 $FONT_PROP->make_default;
1148} 1469}
1149 1470
1150video_init; 1471video_init;
1151audio_init; 1472audio_init;
1152 1473
1153Event::loop; 1474Event::loop;
1154 1475
1155END { CFClient::SDL_Quit } 1476END { CFClient::SDL_Quit }
1156 1477
1478=head1 pclient - Crossfire+ and Crossfire game client
1157 1479
1480Pclient is a Crossfire+ and Crossfire game client.
1481
1482=head2 Features
1483
1484=over 4
1485
1486=item Fullscreen Map
1487
1488PClient can uses a fullscreen map, which greatly enhances how much of the
1489game world you can see.
1490
1491=item Persistent Map Cache (Crossfire+ only)
1492
1493PClient can persistently cache all map data it received from the
1494server. This not only allows it to display an overview map, but also
1495ensures that once-explored areas will be available the next time you want
1496to explore more.
1497
1498=item Hardware acceleration
1499
1500Unlike most Crossfire clients, PClient take advantage of OpenGL hardware
1501acceleration. Most modern graphics cards have difficulties with 2D
1502acceleration, while 3D graphics is accelerated well.
1503
1504=item No arbitrary limits
1505
1506Unlike other Crossfire clients, pclient does not suffer from arbitrary
1507limits (like a fixed amount of face numbers). There are still limits, but
1508they are not arbitrarily low :)
1509
1510=back
1511
1512=head1 FAQ
1513
1514=over 4
1515
1516=item The client is very sluggish and slow, what can I do about this?
1517
1518Most likely, you don't have accelerated OpenGL support. Try to find a
1519newer driver, or a driver from your hardware vendor, that features OpenGL
1520support.
1521
1522If this is not an option, the following Setup options reduce the load and
1523will likely make the client playable with sofwtare rendering (it will
1524still be slow, though):
1525
1526=over 4
1527
1528=item B<Video Mode> should be set as low as possible (e.g. 640x480)
1529
1530=item Enable B<Fast & Ugly> mode
1531
1532=item Disable B<Fog of War>
1533
1534=item Increase B<Map Scale>
1535
1536=back
1537
1538=back
1539
1540=head1 AUTHOR
1541
1542Marc Lehmann <crossfire@schmorp.de>, Robin Redeker <elmex@ta-sa.org>
1543
1544
1545

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines