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.226 by root, Wed May 17 20:21:28 2006 UTC vs.
Revision 1.241 by root, Tue May 23 23:14:46 2006 UTC

82our $BUTTONBAR; 82our $BUTTONBAR;
83our $LOGVIEW; 83our $LOGVIEW;
84our $CONSOLE; 84our $CONSOLE;
85our $METASERVER; 85our $METASERVER;
86our $LOGIN_BUTTON; 86our $LOGIN_BUTTON;
87our $QUIT_DIALOG;
87 88
88our $FLOORBOX; 89our $FLOORBOX;
89our $GAUGES; 90our $GAUGES;
90our $STATWIDS; 91our $STATWIDS;
91 92
105our $INVR; 106our $INVR;
106our $INVR_LBL; 107our $INVR_LBL;
107our $OPENCONT; 108our $OPENCONT;
108 109
109sub status { 110sub status {
110 $STATUSBOX->add ($_[0], pri => -10, group => "status", timeout => 20, fg => [1, 1, 0, 1]); 111 $STATUSBOX->add (CFClient::UI::Label::escape $_[0], pri => -10, group => "status", timeout => 20, fg => [1, 1, 0, 1]);
111} 112}
112 113
113sub debug { 114sub debug {
114 $DEBUG_STATUS->set_text ($_[0]); 115 $DEBUG_STATUS->set_text ($_[0]);
115 my ($w, $h) = $DEBUG_STATUS->size_request; 116 my ($w, $h) = $DEBUG_STATUS->size_request;
209 } 210 }
210 ); 211 );
211 212
212 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Map Scale"); 213 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Map Scale");
213 $table->add (1, $row++, new CFClient::UI::Slider 214 $table->add (1, $row++, new CFClient::UI::Slider
214 range => [$CFG->{map_scale}, 0.25, 2, 0.05, 0.05], 215 range => [(log $CFG->{map_scale}) / (log 2), -3, 1, 0, 1],
215 tooltip => "Enlarge or shrink the displayed map", 216 tooltip => "Enlarge or shrink the displayed map",
216 connect_changed => sub { 217 connect_changed => sub {
217 my ($self, $value) = @_; 218 my ($self, $value) = @_;
218 $CFG->{map_scale} = $value; 219 $CFG->{map_scale} = 2 ** $value;
219 } 220 }
220 ); 221 );
221 222
222 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Fog of War"); 223 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Fog of War");
223 $table->add (1, $row++, new CFClient::UI::CheckBox 224 $table->add (1, $row++, new CFClient::UI::CheckBox
400 (my $hb = new CFClient::UI::HBox), 401 (my $hb = new CFClient::UI::HBox),
401 ], 402 ],
402 ); 403 );
403 404
404 $hb->add (my $hg = new CFClient::UI::Gauge type => 'hp', 405 $hb->add (my $hg = new CFClient::UI::Gauge type => 'hp',
405 tooltip => "Health points. Measures of how much damage you can take before dying. Hit points are determined from your level and are influenced by the value of your Con. Hp value may range between 1 to beyond 500 and higher values indicate a greater ability to withstand punishment."); 406 tooltip => "<b>Health points</b>. Measures of how much damage you can take before dying. Hit points are determined from your level and are influenced by the value of your Con. Hp value may range between 1 to beyond 500 and higher values indicate a greater ability to withstand punishment.");
406 $hb->add (my $mg = new CFClient::UI::Gauge type => 'mana', 407 $hb->add (my $mg = new CFClient::UI::Gauge type => 'mana',
407 tooltip => "Spell points. Measures of how much \"fuel\" you have for casting spells and incantations. Mana is calculated from your level and your Pow. Mana values can range between 1 to beyond 500 (glowing crystals can increase the current spell points beyond your normal maximum). Higher values indicate greater amounts of mana."); 408 tooltip => "<b>Spell points</b>. Measures of how much \"fuel\" you have for casting spells and incantations. Mana is calculated from your level and your Pow. Mana values can range between 1 to beyond 500 (glowing crystals can increase the current spell points beyond your normal maximum). Higher values indicate greater amounts of mana.");
408 $hb->add (my $gg = new CFClient::UI::Gauge type => 'grace', 409 $hb->add (my $gg = new CFClient::UI::Gauge type => 'grace',
409 tooltip => "Grace points - how favored you are by your god. In game terms, how much divine magic you can cast. Your level, Wis and Pow effect what the value of grace is. Prayong on an altar of your god can increase this value beyond your normal maximum. Grace can take on large positive and negative values. Positive values indicate favor by the gods."); 410 tooltip => "<b>Grace points</b> - how favored you are by your god. In game terms, how much divine magic you can cast. Your level, Wis and Pow effect what the value of grace is. Prayong on an altar of your god can increase this value beyond your normal maximum. Grace can take on large positive and negative values. Positive values indicate favor by the gods.");
410 $hb->add (my $fg = new CFClient::UI::Gauge type => 'food', 411 $hb->add (my $fg = new CFClient::UI::Gauge type => 'food',
411 tooltip => "Food. Ranges between 0 (starving) and 999 (satiated). At a value of 0 the character begins to die. Some magic can speed up or slow down the character digestion. Healing wounds will speed up digestion too."); 412 tooltip => "<b>Food</b>. Ranges between 0 (starving) and 999 (satiated). At a value of 0 the character begins to die. Some magic can speed up or slow down the character digestion. Healing wounds will speed up digestion too.");
412 413
413 $vbox->add (my $exp = new CFClient::UI::Label valign => 0, align => 1, can_hover => 1, can_events => 1, 414 $vbox->add (my $exp = new CFClient::UI::Label valign => 0, align => 1, can_hover => 1, can_events => 1,
414 tooltip => "Experience points and overall level - experience is increased as a reward for appropriate action (such as killing monsters) and may decrease as a result of a magical attack or dying. Level is directly derived from the experience value. As the level of the character increases, the character becomes able to succeed at more difficult tasks. A character's level starts at a value of 0 and may range up beyond 100."); 415 tooltip => "<b>Experience points and overall level</b> - experience is increased as a reward for appropriate action (such as killing monsters) and may decrease as a result of a magical attack or dying. Level is directly derived from the experience value. As the level of the character increases, the character becomes able to succeed at more difficult tasks. A character's level starts at a value of 0 and may range up beyond 100.");
415 $vbox->add (my $rng = new CFClient::UI::Label valign => 0, align => 1, can_hover => 1, can_events => 1, 416 $vbox->add (my $rng = new CFClient::UI::Label valign => 0, align => 1, can_hover => 1, can_events => 1,
416 tooltip => "Ranged attack - how you attack when you press shift-cursor (spell, skill, weapon etc.)"); 417 tooltip => "<b>Ranged attack</b> - how you attack when you press shift-cursor (spell, skill, weapon etc.)");
417 418
418 $GAUGES = { 419 $GAUGES = {
419 exp => $exp, win => $win, range => $rng, 420 exp => $exp, win => $win, range => $rng,
420 food => $fg, mana => $mg, hp => $hg, grace => $gg 421 food => $fg, mana => $mg, hp => $hg, grace => $gg
421 }; 422 };
424 425
425 $win 426 $win
426} 427}
427 428
428sub make_stats_window { 429sub make_stats_window {
429 my $tgw = new CFClient::UI::FancyFrame x => $WIDTH * 2/5, y => 0, title => "Stats"; 430 my $tgw = new CFClient::UI::FancyFrame title => "Stats";
430 431
431 $tgw->add (new CFClient::UI::Window child => my $vb = new CFClient::UI::VBox); 432 $tgw->add (new CFClient::UI::Window child => my $vb = new CFClient::UI::VBox);
432 $vb->add ($STATWIDS->{title} = new CFClient::UI::Label valign => 0, align => -1, text => "Title:", expand => 1); 433 $vb->add ($STATWIDS->{title} = new CFClient::UI::Label valign => 0, align => -1, text => "Title:", expand => 1,
434 can_hover => 1, can_events => 1,
435 tooltip => "Your name and title. You can change your title by using the <b>title</b> command, if supported by the server.");
433 $vb->add ($STATWIDS->{map} = new CFClient::UI::Label valign => 0, align => -1, text => "Map:", expand => 1); 436 $vb->add ($STATWIDS->{map} = new CFClient::UI::Label valign => 0, align => -1, text => "Map:", expand => 1,
437 can_hover => 1, can_events => 1,
438 tooltip => "The map you are currently on (if supported by the server).");
434 439
435 $vb->add (my $hb = new CFClient::UI::HBox expand => 1); 440 $vb->add (my $hb = new CFClient::UI::HBox expand => 1);
436
437 $hb->add (my $tbl = new CFClient::UI::Table expand => 1); 441 $hb->add (my $tbl = new CFClient::UI::Table expand => 1);
438 442
439 my $black = [0, 0, 0]; 443 my $color2 = [1, 1, 0];
440 444
441 for ( 445 for (
442 [0, 0, st_str => "Str", 30, "Physical Strength, determines damage dealt with weapons, how much you can carry, and how often you can attack"], 446 [0, 0, st_str => "Str", 30, "<b>Physical Strength</b>, determines damage dealt with weapons, how much you can carry, and how often you can attack"],
443 [0, 1, st_dex => "Dex", 30, "Dexterity, your physical agility. Determines chance of being hit and affects armor class and speed"], 447 [0, 1, st_dex => "Dex", 30, "<b>Dexterity</b>, your physical agility. Determines chance of being hit and affects armor class and speed"],
444 [0, 2, st_con => "Con", 30, "Constitution, physical health and toughness. Determines how many healthpoints you can have"], 448 [0, 2, st_con => "Con", 30, "<b>Constitution</b>, physical health and toughness. Determines how many healthpoints you can have"],
445 [0, 3, st_int => "Int", 30, "Intelligence, your ability to learn and use skills and incantations (both prayers and magic) and determines how much spell points you can have"], 449 [0, 3, st_int => "Int", 30, "<b>Intelligence</b>, your ability to learn and use skills and incantations (both prayers and magic) and determines how much spell points you can have"],
446 [0, 4, st_wis => "Wis", 30, "Wisdom, the ability to learn and use divine magic (prayers). Determines how many grace points you can have"], 450 [0, 4, st_wis => "Wis", 30, "<b>Wisdom</b>, the ability to learn and use divine magic (prayers). Determines how many grace points you can have"],
447 [0, 5, st_pow => "Pow", 30, "Power, your magical potential. Influences the strength of spell effects, and also how much your spell and grace points increase when leveling up"], 451 [0, 5, st_pow => "Pow", 30, "<b>Power</b>, your magical potential. Influences the strength of spell effects, and also how much your spell and grace points increase when leveling up"],
448 [0, 6, st_cha => "Cha", 30, "Charisma, how well you are received by NPCs. Affects buying and selling prices in shops."], 452 [0, 6, st_cha => "Cha", 30, "<b>Charisma</b>, how well you are received by NPCs. Affects buying and selling prices in shops."],
449 453
450 [2, 0, st_wc => "Wc", -120, "Weapon Class, effectiveness of melee/missile attacks. Lower is more potent. Current weapon, level and Str are some things which effect the value of Wc. The value of Wc may range between 25 and -72."], 454 [2, 0, st_wc => "Wc", -120, "<b>Weapon Class</b>, effectiveness of melee/missile attacks. Lower is more potent. Current weapon, level and Str are some things which effect the value of Wc. The value of Wc may range between 25 and -72."],
451 [2, 1, st_ac => "Ac", -120, "Armour Class, how protected you are from being hit by any attack. Lower values are better. Ac is based on your race and is modified by the Dex and current armour worn. For characters that cannot wear armour, Ac improves as their level increases."], 455 [2, 1, st_ac => "Ac", -120, "<b>Armour Class</b>, how protected you are from being hit by any attack. Lower values are better. Ac is based on your race and is modified by the Dex and current armour worn. For characters that cannot wear armour, Ac improves as their level increases."],
452 [2, 2, st_dam => "Dam", 120, "Damage, how much damage your melee/missile attack inflicts. Higher values indicate a greater amount of damage will be inflicted with each attack."], 456 [2, 2, st_dam => "Dam", 120, "<b>Damage</b>, how much damage your melee/missile attack inflicts. Higher values indicate a greater amount of damage will be inflicted with each attack."],
453 [2, 3, st_arm => "Arm", 120, "Armour, how much damage (from physical attacks) will be subtracted from successful hits made upon you. This value ranges between 0 to 99%. Current armour worn primarily determines Arm value."], 457 [2, 3, st_arm => "Arm", 120, "<b>Armour</b>, how much damage (from physical attacks) will be subtracted from successful hits made upon you. This value ranges between 0 to 99%. Current armour worn primarily determines Arm value."],
454 [2, 4, st_spd => "Spd", 10.54, "Speed, how fast you can move. The value of speed may range between nearly 0 (\"very slow\") to higher than 5 (\"lightning fast\"). Base speed is determined from the Dex and modified downward proportionally by the amount of weight carried which exceeds the Max Carry limit. The armour worn also sets the upper limit on speed."], 458 [2, 4, st_spd => "Spd", 10.54, "<b>Speed</b>, how fast you can move. The value of speed may range between nearly 0 (\"very slow\") to higher than 5 (\"lightning fast\"). Base speed is determined from the Dex and modified downward proportionally by the amount of weight carried which exceeds the Max Carry limit. The armour worn also sets the upper limit on speed."],
455 [2, 5, st_wspd => "WSp", 10.54, "Weapon Speed, how many attacks you may make per unit of time (0.120s). Higher values indicate faster attack speed. Current weapon and Dex effect the value of weapon speed."], 459 [2, 5, st_wspd => "WSp", 10.54, "<b>Weapon Speed</b>, how many attacks you may make per unit of time (0.120s). Higher values indicate faster attack speed. Current weapon and Dex effect the value of weapon speed."],
456 ) { 460 ) {
457 my ($col, $row, $id, $label, $template, $tooltip) = @$_; 461 my ($col, $row, $id, $label, $template, $tooltip) = @$_;
458 462
459 $tbl->add ($col , $row, $STATWIDS->{$id} = new CFClient::UI::Label 463 $tbl->add ($col , $row, $STATWIDS->{$id} = new CFClient::UI::Label
460 font => $FONT_FIXED, can_hover => 1, can_events => 1, valign => 0, align => +1, template => $template, tooltip => $tooltip); 464 font => $FONT_FIXED, can_hover => 1, can_events => 1, valign => 0, align => +1, template => $template, tooltip => $tooltip);
461 $tbl->add ($col + 1, $row, $STATWIDS->{"$id\_lbl"} = new CFClient::UI::Label 465 $tbl->add ($col + 1, $row, $STATWIDS->{"$id\_lbl"} = new CFClient::UI::Label
462 font => $FONT_FIXED, can_hover => 1, can_events => 1, fg => $black, valign => 0, align => -1, text => $label, tooltip => $tooltip); 466 font => $FONT_FIXED, can_hover => 1, can_events => 1, fg => $color2, valign => 0, align => -1, text => $label, tooltip => $tooltip);
463 } 467 }
464 468
465 $hb->add (my $tbl2 = new CFClient::UI::Table expand => 1); 469 $hb->add (my $tbl2 = new CFClient::UI::Table expand => 1);
466 470
467 my $row = 0; 471 my $row = 0;
468 my $col = 0; 472 my $col = 0;
469 473
470 my %resist_names = ( 474 my %resist_names = (
471 slow => "Slow (slows you down when you are hit by the spell. Monsters will have an opportunity to come near you faster and hit you more often.)", 475 slow => "<b>Slow</b> (slows you down when you are hit by the spell. Monsters will have an opportunity to come near you faster and hit you more often.)",
472 holyw => "Holy Word (resistance you against getting the fear when someone whose god doesn't like you spells the holy word on you.)", 476 holyw => "<b>Holy Word</b> (resistance you against getting the fear when someone whose god doesn't like you spells the holy word on you.)",
473 conf => "Confusion (If you are hit by confusion you will move into random directions, and likely into monsters.)", 477 conf => "<b>Confusion</b> (If you are hit by confusion you will move into random directions, and likely into monsters.)",
474 fire => "Fire (just your resistance to fire spells like burning hands, dragonbreath, meteor swarm fire, ...)", 478 fire => "<b>Fire</b> (just your resistance to fire spells like burning hands, dragonbreath, meteor swarm fire, ...)",
475 depl => "Depletion (some monsters and other effects can cause stats depletion)", 479 depl => "<b>Depletion</b> (some monsters and other effects can cause stats depletion)",
476 magic => "Magic (resistance to magic spells like magic missile or similar)", 480 magic => "<b>Magic</b> (resistance to magic spells like magic missile or similar)",
477 drain => "Draining (some monsters (e.g. vampires) and other effects can steal experience)", 481 drain => "<b>Draining</b> (some monsters (e.g. vampires) and other effects can steal experience)",
478 acid => "Acid (resistance to acid, acid hurts pretty much and also corrodes your weapons)", 482 acid => "<b>Acid</b> (resistance to acid, acid hurts pretty much and also corrodes your weapons)",
479 pois => "Poison (resistance to getting poisoned)", 483 pois => "<b>Poison</b> (resistance to getting poisoned)",
480 para => "Paralysation (this resistance affects the chance you get paralysed)", 484 para => "<b>Paralysation</b> (this resistance affects the chance you get paralysed)",
481 deat => "Death (resistance against death spells)", 485 deat => "<b>Death</b> (resistance against death spells)",
482 phys => "Physical (this is the resistance against physical attacks, like when a monster hit you in melee combat)", 486 phys => "<b>Physical</b> (this is the resistance against physical attacks, like when a monster hit you in melee combat)",
483 blind => "Blind (blind resistance affects the chance of a successful blinding attack)", 487 blind => "<b>Blind</b> (blind resistance affects the chance of a successful blinding attack)",
484 fear => "Fear (this attack will drive you away from monsters who cast this and hit you successfully, being resistant to this helps a lot when fighting those monsters)", 488 fear => "<b>Fear</b> (this attack will drive you away from monsters who cast this and hit you successfully, being resistant to this helps a lot when fighting those monsters)",
485 tund => "Turn undead", 489 tund => "<b>Turn undead</b> (affects your resistancy to various forms of 'turn undead' spells. Only relevant when you are, in fact, undead...",
486 elec => "Electricity (resistance againt electricity, spells like large lightning, small lightning, ...)", 490 elec => "<b>Electricity</b> (resistance against electricity, spells like large lightning, small lightning, ...)",
487 cold => "Cold (this is your resistance against cold spells like icestorm, snowstorm, ...)", 491 cold => "<b>Cold</b> (this is your resistance against cold spells like icestorm, snowstorm, ...)",
488 ghit => "Ghost hit (special attack used by ghosts and ghost-like beings)", 492 ghit => "<b>Ghost hit</b> (special attack used by ghosts and ghost-like beings)",
489 ); 493 );
490 for (qw/slow holyw conf fire depl magic 494 for (qw/slow holyw conf fire depl magic
491 drain acid pois para deat phys 495 drain acid pois para deat phys
492 blind fear tund elec cold ghit/) 496 blind fear tund elec cold ghit/)
493 { 497 {
781 785
782sub message_window { 786sub message_window {
783 my $window = new CFClient::UI::FancyFrame 787 my $window = new CFClient::UI::FancyFrame
784 title => "Messages", 788 title => "Messages",
785 border_bg => [1, 1, 1, 1], 789 border_bg => [1, 1, 1, 1],
786 bg => [0, 0, 0, 0.5], 790 bg => [0, 0, 0, 0.75],
787 user_w => int $::WIDTH / 3, 791 user_w => int $::WIDTH / 3,
788 user_h => int $::HEIGHT / 5, 792 user_h => int $::HEIGHT / 5,
789 child => (my $vbox = new CFClient::UI::VBox); 793 child => (my $vbox = new CFClient::UI::VBox);
790 794
791 $vbox->add ($LOGVIEW = new CFClient::UI::TextView 795 $vbox->add ($LOGVIEW);
792 expand => 1,
793 font => $FONT_FIXED,
794 fontsize => $::CFG->{log_fontsize},
795 );
796 796
797 $vbox->add (my $input = new CFClient::UI::Entry 797 $vbox->add (my $input = new CFClient::UI::Entry
798 tooltip => "<b>Chat Box</b>. If you enter a text and press return/enter here, the current <i>communication command</i> "
799 . "from the client setup will be prepended (e.g. <b>shout</b>, <b>chat</b>...). "
800 . "If you prepend a slash (/), you will submit a command instead (similar to IRC). "
801 . "A better way to submit commands (and the occasional chat command) is often the map command completer.",
798 connect_focus_in => sub { 802 connect_focus_in => sub {
799 my ($input, $prev_focus) = @_; 803 my ($input, $prev_focus) = @_;
800 804
801 delete $input->{refocus_map}; 805 delete $input->{refocus_map};
802 806
831 }; 835 };
832 836
833 $window 837 $window
834} 838}
835 839
840sub open_quit_dialog {
841 unless ($QUIT_DIALOG) {
842
843 $QUIT_DIALOG = new CFClient::UI::FancyFrame title => "Really Quit?";
844
845 $QUIT_DIALOG->add (my $vb = new CFClient::UI::VBox expand => 1);
846
847 $vb->add (new CFClient::UI::Label
848 text => "You should find a savebed and apply it first!",
849 max_w => $WIDTH * 0.25
850 );
851 $vb->add (my $hb = new CFClient::UI::HBox expand => 1);
852 $hb->add (new CFClient::UI::Button
853 text => "Ok",
854 connect_activate => sub { $QUIT_DIALOG->hide },
855 expand => 1
856 );
857 $hb->add (new CFClient::UI::Button
858 text => "Quit anyway",
859 connect_activate => sub { exit 1 },
860 expand => 1
861 );
862 $hb->add (new CFClient::UI::Label "You should find a savebed and apply it first!");
863
864 $QUIT_DIALOG->show_centered;
865 } else {
866 $QUIT_DIALOG->show_centered;
867 }
868}
869
836sub make_inventory_window { 870sub make_inventory_window {
837 my $invwin = new CFClient::UI::FancyFrame 871 my $invwin = new CFClient::UI::FancyFrame
838 user_w => $WIDTH * (4/5), user_h => $HEIGHT * (4/5), title => "Inventory"; 872 user_w => $WIDTH * (7/8), user_h => $HEIGHT * (7/8), title => "Inventory";
839 873
840 $invwin->add (my $hb = new CFClient::UI::HBox); 874 $invwin->add (my $hb = new CFClient::UI::HBox expand => 1);
841 875
842 $hb->add (my $vb1 = new CFClient::UI::VBox expand => 1); 876 $hb->add (my $vb1 = new CFClient::UI::VBox expand => 1);
843 $vb1->add (my $lbl = new CFClient::UI::Label); 877 $vb1->add (my $lbl = new CFClient::UI::Label);
844 $lbl->set_text ("Player"); 878 $lbl->set_text ("Player");
845 $vb1->add ($INV = new CFClient::UI::Inventory expand => 1); 879 $vb1->add ($INV = new CFClient::UI::Inventory expand => 1);
850 $vb2->add ($INVR = new CFClient::UI::Inventory expand => 1); 884 $vb2->add ($INVR = new CFClient::UI::Inventory expand => 1);
851 885
852 $invwin 886 $invwin
853} 887}
854 888
889sub make_help_window {
890 my $win = new CFClient::UI::FancyFrame
891 user_w => $WIDTH * (7/8), user_h => $HEIGHT * (7/8), title => "Documentation";
892
893 $win->add (my $vbox = new CFClient::UI::VBox);
894
895 $vbox->add (my $buttons = new CFClient::UI::HBox);
896 $vbox->add (my $viewer = new CFClient::UI::TextView expand => 1, fontsize => 0.8);
897
898 for (
899 [intro => "Introduction"],
900 [command_help => "Commands"],
901 [skill_help => "Skills"],
902 ) {
903 my ($pod, $label) = @$_;
904
905 $buttons->add (new CFClient::UI::Button
906 text => $label,
907 connect_activate => sub {
908 my $parser = new Pod::POM;
909 my $pom = $parser->parse_file (CFClient::find_rcfile "pod/$pod.pod");
910
911 $viewer->clear;
912
913 $viewer->add_paragraph ([1, 1, 1, 1], $_->[1], $_->[0])
914 for @{ CFClient::pod_to_pango_list $pom };
915 },
916 );
917 }
918
919 $viewer->add_paragraph ([1, 1, 0, 1], "<big>Use one of the buttons above to display a document.</big>");
920
921 $win
922}
923
855sub sdl_init { 924sub sdl_init {
856 CFClient::SDL_Init 925 CFClient::SDL_Init
857 and die "SDL::Init failed!\n"; 926 and die "SDL::Init failed!\n";
858} 927}
859 928
865 ($WIDTH, $HEIGHT) = @{ $SDL_MODES[$CFG->{sdl_mode}] }; 934 ($WIDTH, $HEIGHT) = @{ $SDL_MODES[$CFG->{sdl_mode}] };
866 $FULLSCREEN = $CFG->{fullscreen}; 935 $FULLSCREEN = $CFG->{fullscreen};
867 $FAST = $CFG->{fast}; 936 $FAST = $CFG->{fast};
868 937
869 CFClient::SDL_SetVideoMode $WIDTH, $HEIGHT, $FULLSCREEN 938 CFClient::SDL_SetVideoMode $WIDTH, $HEIGHT, $FULLSCREEN
870 or die "SDL_SetVideoMode failed!\n"; 939 or die "SDL_SetVideoMode failed: " . (CFClient::SDL_GetError) . "\n";
871 940
872 $SDL_ACTIVE = 1; 941 $SDL_ACTIVE = 1;
873 $LAST_REFRESH = time - 0.01; 942 $LAST_REFRESH = time - 0.01;
874 943
875 CFClient::gl_init; 944 CFClient::gl_init;
896 )->show; 965 )->show;
897 966
898 CFClient::UI::FancyFrame->new ( 967 CFClient::UI::FancyFrame->new (
899 border_bg => [1, 1, 1, 192/255], 968 border_bg => [1, 1, 1, 192/255],
900 bg => [1, 1, 1, 0], 969 bg => [1, 1, 1, 0],
901 child => ($MAPMAP = new CFClient::MapWidget::MapMap), 970 child => ($MAPMAP = new CFClient::MapWidget::MapMap
971 tooltip => "<b>Map</b>. On servers that support this feature, this will display an overview of the surrounding areas.",
972 ),
902 )->show; 973 )->show;
903 974
904 $MAPWIDGET = new CFClient::MapWidget; 975 $MAPWIDGET = new CFClient::MapWidget;
905 $MAPWIDGET->connect (activate_console => sub { 976 $MAPWIDGET->connect (activate_console => sub {
906 my ($mapwidget, $preset) = @_; 977 my ($mapwidget, $preset) = @_;
915 } 986 }
916 }); 987 });
917 $MAPWIDGET->show; 988 $MAPWIDGET->show;
918 $MAPWIDGET->focus_in; 989 $MAPWIDGET->focus_in;
919 990
991 $LOGVIEW = new CFClient::UI::TextView
992 expand => 1,
993 font => $FONT_FIXED,
994 fontsize => $::CFG->{log_fontsize},
995 can_hover => 1,
996 can_events => 1,
997 tooltip => "<b>Server Log</b>. This text viewer contains all the messages sent by the server.",
998 ;
999
920 $BUTTONBAR = new CFClient::UI::HBox; 1000 $BUTTONBAR = new CFClient::UI::HBox;
921 1001
922 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Client Setup", other => client_setup); 1002 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Client Setup", other => client_setup,
1003 tooltip => "Toggles a dialog where you can configure various aspects of the client, such as graphics mode, performance, and audio options.");
923 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Server Setup", other => server_setup); 1004 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Server Setup", other => server_setup,
1005 tooltip => "Toggles a dialog where you can configure the server to play on, your username, password and other server-related options.");
924 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Message Window", other => message_window); 1006 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Message Window", other => message_window,
1007 tooltip => "Toggles the server message log, where the client collects <i>all</i> messages from the server.");
925 1008
926 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 1009 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
927 1010
928 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Stats Window", other => make_stats_window); 1011 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Stats Window", other => make_stats_window,
1012 tooltip => "Toggles the statistics window, where all your Stats and Resistances are beign displaye at all times.");
929 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Inventory", other => make_inventory_window); 1013 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Inventory", other => make_inventory_window,
1014 tooltip => "Toggles the inventory window, where you can manage your loot (or treaures :).");
930 1015
931 $BUTTONBAR->add (new CFClient::UI::Button text => "Save Config", connect_activate => sub { 1016 $BUTTONBAR->add (new CFClient::UI::Button
1017 text => "Save Config",
1018 tooltip => "Saves the options chosen in the client setting, server settings and the window layout to be restored on later runs.",
1019 connect_activate => sub {
932 CFClient::write_cfg "$Crossfire::VARDIR/pclientrc"; 1020 CFClient::write_cfg "$Crossfire::VARDIR/pclientrc";
933 status "Configuration Saved"; 1021 status "Configuration Saved";
1022 },
934 }); 1023 );
1024
1025 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Help!", other => make_help_window,
1026 tooltip => "View Documentation");
1027
1028 $BUTTONBAR->add (new CFClient::UI::Button
1029 text => "Quit",
1030 tooltip => "Terminates the program",
1031 connect_activate => sub {
1032 if ($CONN) {
1033 open_quit_dialog;
1034 } else {
1035 exit;
1036 }
1037 },
1038 );
935 1039
936 $BUTTONBAR->show; 1040 $BUTTONBAR->show;
937 1041
938 $STATUSBOX->add ("Set video mode $WIDTH×$HEIGHT", timeout => 10, fg => [1, 1, 1, 0.5]); 1042 $STATUSBOX->add ("Set video mode $WIDTH×$HEIGHT", timeout => 10, fg => [1, 1, 1, 0.5]);
939 1043
972 1076
973sub audio_init { 1077sub audio_init {
974 if ($CFG->{audio_enable}) { 1078 if ($CFG->{audio_enable}) {
975 if (open my $fh, "<", CFClient::find_rcfile "sounds/config") { 1079 if (open my $fh, "<", CFClient::find_rcfile "sounds/config") {
976 $SDL_MIXER = !CFClient::Mix_OpenAudio; 1080 $SDL_MIXER = !CFClient::Mix_OpenAudio;
1081
1082 unless ($SDL_MIXER) {
1083 status "Unable to open sound device: there will be no sound";
1084 return;
1085 }
1086
977 CFClient::Mix_AllocateChannels 8; 1087 CFClient::Mix_AllocateChannels 8;
978 CFClient::MixMusic::volume $CFG->{bgm_volume} * 128; 1088 CFClient::MixMusic::volume $CFG->{bgm_volume} * 128;
979 1089
980 audio_music_finished; 1090 audio_music_finished;
981 1091
1009my %animate_object; 1119my %animate_object;
1010my $animate_timer; 1120my $animate_timer;
1011 1121
1012my $fps = 9; 1122my $fps = 9;
1013 1123
1124my %demo;#d#
1125
1014sub force_refresh { 1126sub force_refresh {
1015 $fps = $fps * 0.95 + 1 / (($NOW - $LAST_REFRESH) || 0.1) * 0.05; 1127 $fps = $fps * 0.95 + 1 / (($NOW - $LAST_REFRESH) || 0.1) * 0.05;
1016 debug sprintf "%3.2f", $fps; 1128 debug sprintf "%3.2f", $fps;
1017 1129
1018 $CFClient::UI::ROOT->draw; 1130 $CFClient::UI::ROOT->draw;
1019 CFClient::SDL_GL_SwapBuffers;
1020 1131
1021 $WANT_REFRESH = 0; 1132 $WANT_REFRESH = 0;
1022 $CAN_REFRESH = 0; 1133 $CAN_REFRESH = 0;
1023 $LAST_REFRESH = $NOW; 1134 $LAST_REFRESH = $NOW;
1135
11360 && do {
1137 # some weird model-drawing code, just a joke right now
1138 use CFClient::OpenGL;
1139
1140 $demo{t}{eye_auv} ||= new_from_file CFClient::Texture "eye2.png" or die;
1141 $demo{t}{body_auv} ||= new_from_file CFClient::Texture "body_auv3.png" or die;
1142 $demo{r} ||= do {
1143 my $mod = Compress::LZF::sthaw do { local $/; open my $fh, "<:raw:perlio", "dread.lz3"; <$fh> };
1144 $mod->{v} = pack "f*", @{$mod->{v}};
1145 $_ = [scalar @$_, pack "S!*", @$_]
1146 for values %{$mod->{g}};
1147 $mod
1148 };
1149
1150 my $r = $demo{r} or die;
1151
1152 glDepthMask 1;
1153 glClear GL_DEPTH_BUFFER_BIT;
1154 glEnable GL_TEXTURE_2D;
1155 glEnable GL_DEPTH_TEST;
1156 glEnable GL_CULL_FACE;
1157 glShadeModel $::FAST ? GL_FLAT : GL_SMOOTH;
1158
1159 glMatrixMode GL_PROJECTION;
1160 glLoadIdentity;
1161 glFrustum -1 * ($::WIDTH / $::HEIGHT), 1 * ($::WIDTH / $::HEIGHT), 1, -1, 1, 10000;
1162 #glOrtho 0, $::WIDTH, 0, $::HEIGHT, -10000, 10000;
1163 glMatrixMode GL_MODELVIEW;
1164 glLoadIdentity;
1165
1166 glPushMatrix;
1167 glTranslate 0, 0, -800;
1168 glScale 1, -1, 1;
1169 glRotate $NOW * 1000 % 36000 / 5, 0, 1, 0;
1170 glRotate $NOW * 1000 % 36000 / 6, 1, 0, 0;
1171 glRotate $NOW * 1000 % 36000 / 7, 0, 0, 1;
1172 glScale 50, 50, 50;
1173
1174 glInterleavedArrays GL_T2F_N3F_V3F, 0, $r->{v};
1175 while (my ($k, $v) = each %{$r->{g}}) {
1176 glBindTexture GL_TEXTURE_2D, ($demo{t}{$k}{name} or die);
1177 glDrawElements GL_TRIANGLES, $v->[0], GL_UNSIGNED_SHORT, $v->[1];
1178 }
1179
1180 glPopMatrix;
1181
1182 glShadeModel GL_FLAT;
1183 glDisable GL_DEPTH_TEST;
1184 glDisable GL_TEXTURE_2D;
1185 glDepthMask 0;
1186
1187 $WANT_REFRESH++;
1188};
1189
1190 CFClient::SDL_GL_SwapBuffers;
1024} 1191}
1025 1192
1026my $refresh_watcher = Event->timer (after => 0, hard => 1, interval => 1 / $MAX_FPS, cb => sub { 1193my $refresh_watcher = Event->timer (after => 0, hard => 1, interval => 1 / $MAX_FPS, cb => sub {
1027 $NOW = time; 1194 $NOW = time;
1028 1195
1070 my $cmd = $1; 1237 my $cmd = $1;
1071 my @args = split /\|/, $2; 1238 my @args = split /\|/, $2;
1072 @args = (".*") unless @args; 1239 @args = (".*") unless @args;
1073 1240
1074 my $text = CFClient::pod_to_pango $head2->content; 1241 my $text = CFClient::pod_to_pango $head2->content;
1242 my @par = CFClient::pod_to_pango_list $head2->content; use Data::Dumper; warn Dumper \@par;#d#
1075 1243
1076 for my $arg (@args) { 1244 for my $arg (@args) {
1077 $arg = $arg eq ".*" ? "" : " $arg"; 1245 $arg = $arg eq ".*" ? "" : " $arg";
1078 1246
1079 $MAPWIDGET->add_command ("$cmd$arg", $text); 1247 $MAPWIDGET->add_command ("$cmd$arg", $text);
1080 } 1248 }
1081 } 1249 }
1250
1251 $self->{noface} = new_from_file CFClient::Texture
1252 CFClient::find_rcfile "noface.png", minify => 1, mipmap => 1;
1082 1253
1083 $self 1254 $self
1084} 1255}
1085 1256
1086sub conn::stats_update { 1257sub conn::stats_update {
1154 $self->set_texture ($id => $data); 1325 $self->set_texture ($id => $data);
1155 } 1326 }
1156 } 1327 }
1157} 1328}
1158 1329
1330# hardcode /world/world_xxx_xxx map names, the savings are enourmous,
1331# (server resource,s latency, bandwidth), so this hack is warranted.
1332# the right fix is to make real tiled maps with an overview file
1333sub conn::send_mapinfo {
1334 my ($self, $data, $cb) = @_;
1335
1336 if ($self->{map_info}[0] =~ m%^/world/world_(\d\d\d)_(\d\d\d)$%) {
1337 my ($wx, $wy) = ($1, $2);
1338
1339 if ($data =~ /^spatial ([1-4]+)$/) {
1340 my @dx = (0, 0, 1, 0, -1);
1341 my @dy = (0, -1, 0, 1, 0);
1342 my ($dx, $dy);
1343
1344 for (split //, $1) {
1345 $dx += $dx[$_];
1346 $dy += $dy[$_];
1347 }
1348
1349 $cb->(spatial => 15,
1350 $self->{map_info}[1] - $MAP->ox + $dx * 50,
1351 $self->{map_info}[2] - $MAP->oy + $dy * 50,
1352 50, 50,
1353 sprintf "/world/world_%03d_%03d", $wx + $dx, $wy + $dy
1354 );
1355
1356 return;
1357 }
1358 }
1359
1360 $self->SUPER::send_mapinfo ($data, $cb);
1361}
1362
1159# this method does a "flood fill" into every tile direction 1363# this method does a "flood fill" into every tile direction
1160# it assumes that tiles are arranged in a rectangular grid, 1364# it assumes that tiles are arranged in a rectangular grid,
1161# i.e. a map is the same as the left of the right map etc. 1365# i.e. a map is the same as the left of the right map etc.
1162# failure to comply are harmless and result in display errors 1366# failure to comply are harmless and result in display errors
1163# at worst. 1367# at worst.
1164sub conn::flood_fill { 1368sub conn::flood_fill {
1165 my ($self, $gx, $gy, $path, $hash, $flags) = @_; 1369 my ($self, $block, $gx, $gy, $path, $hash, $flags) = @_;
1166 1370
1167 # the server does not allow map paths > 6 1371 # the server does not allow map paths > 6
1168 return if 7 <= length $path; 1372 return if 7 <= length $path;
1169 1373
1170 my ($x0, $y0, $x1, $y1) = @{$self->{neigh_rect}}; 1374 my ($x0, $y0, $x1, $y1) = @{$self->{neigh_rect}};
1171 1375
1172 for ( 1376 for (
1173 [1, 0, -1], 1377 [1, 3, 0, -1],
1174 [2, 1, 0], 1378 [2, 4, 1, 0],
1175 [3, 0, 1], 1379 [3, 1, 0, 1],
1176 [4, -1, 0], 1380 [4, 2, -1, 0],
1177 ) { 1381 ) {
1178 my ($tile, $dx, $dy) = @$_; 1382 my ($tile, $tile2, $dx, $dy) = @$_;
1383
1384 next if $block & (1 << $tile);
1385 my $block = $block | (1 << $tile2);
1179 1386
1180 my $gx = $gx + $dx; 1387 my $gx = $gx + $dx;
1181 my $gy = $gy + $dy; 1388 my $gy = $gy + $dy;
1182 1389
1183 next unless $flags & (1 << ($tile - 1)); 1390 next unless $flags & (1 << ($tile - 1));
1185 1392
1186 my $neigh = $self->{neigh_map}{$hash} ||= []; 1393 my $neigh = $self->{neigh_map}{$hash} ||= [];
1187 if (my $info = $neigh->[$tile]) { 1394 if (my $info = $neigh->[$tile]) {
1188 my ($flags, $x, $y, $w, $h, $hash) = @$info; 1395 my ($flags, $x, $y, $w, $h, $hash) = @$info;
1189 1396
1190 $self->flood_fill ($gx, $gy, "$path$tile", $hash, $flags) 1397 $self->flood_fill ($block, $gx, $gy, "$path$tile", $hash, $flags)
1191 if $x >= $x0 && $x + $w < $x1 && $y >= $y0 && $y + $h < $y1; 1398 if $x >= $x0 && $x + $w < $x1 && $y >= $y0 && $y + $h < $y1;
1192 1399
1193 } else { 1400 } else {
1194 $self->send_mapinfo ("spatial $path$tile", sub { 1401 $self->send_mapinfo ("spatial $path$tile", sub {
1195 my ($mode, $flags, $x, $y, $w, $h, $hash) = @_; 1402 my ($mode, $flags, $x, $y, $w, $h, $hash) = @_;
1196 1403
1197 return if $mode ne "spatial"; 1404 return if $mode ne "spatial";
1198 1405
1199 $x += $MAP->ox; 1406 $x += $MAP->ox;
1200 $y += $MAP->oy; 1407 $y += $MAP->oy;
1201 1408
1202 $self->load_map ($hash, $x, $y) 1409 $self->load_map ($hash, $x, $y)
1203 unless $self->{neigh_map}{$hash}[5]++;#d# 1410 unless $self->{neigh_map}{$hash}[5]++;#d#
1204 1411
1205 $neigh->[$tile] = [$flags, $x, $y, $w, $h, $hash]; 1412 $neigh->[$tile] = [$flags, $x, $y, $w, $h, $hash];
1206 1413
1207 $self->flood_fill ($gx, $gy, "$path$tile", $hash, $flags) 1414 $self->flood_fill ($block, $gx, $gy, "$path$tile", $hash, $flags)
1208 if $x >= $x0 && $x + $w < $x1 && $y >= $y0 && $y + $h < $y1; 1415 if $x >= $x0 && $x + $w < $x1 && $y >= $y0 && $y + $h < $y1;
1209 }); 1416 });
1210 } 1417 }
1211 } 1418 }
1212} 1419}
1225 $ox - $mapmapw * 0.5, $oy - $mapmapw * 0.5, 1432 $ox - $mapmapw * 0.5, $oy - $mapmapw * 0.5,
1226 $ox + $mapmapw * 0.5 + $w, $oy + $mapmapw * 0.5 + $h, 1433 $ox + $mapmapw * 0.5 + $w, $oy + $mapmapw * 0.5 + $h,
1227 ]; 1434 ];
1228 1435
1229 delete $self->{neigh_grid}; 1436 delete $self->{neigh_grid};
1230 $self->flood_fill (0, 0, "", $hash, $flags);
1231 1437
1232 $x += $ox; 1438 $x += $ox;
1233 $y += $oy; 1439 $y += $oy;
1234 1440
1235 $self->{map_info} = [$hash, $x, $y, $w, $h]; 1441 $self->{map_info} = [$hash, $x, $y, $w, $h];
1236 1442
1237 my $map = $self->{map_info}[0];
1238 $map =~ s/^.*?\/([^\/]+)$/\1/; 1443 (my $map = $hash) =~ s/^.*?\/([^\/]+)$/\1/;
1239 $STATWIDS->{map}->set_text ("Map: " . $map); 1444 $STATWIDS->{map}->set_text ("Map: " . $map);
1240 1445
1241 $self->load_map ($hash, $x, $y); 1446 $self->load_map ($hash, $x, $y);
1447 $self->flood_fill (0, 0, 0, "", $hash, $flags);
1242} 1448}
1243 1449
1244sub conn::face_find { 1450sub conn::face_find {
1245 my ($self, $facenum, $face) = @_; 1451 my ($self, $facenum, $face) = @_;
1246 1452
1248 1454
1249 my $id = $FACEMAP->get ($hash); 1455 my $id = $FACEMAP->get ($hash);
1250 1456
1251 unless ($id) { 1457 unless ($id) {
1252 # create new id for face 1458 # create new id for face
1253 # i love transactions 1459 # I love transactions
1254 for (1..100) { 1460 for (1..100) {
1255 my $txn = $CFClient::DB_ENV->txn_begin; 1461 my $txn = $CFClient::DB_ENV->txn_begin;
1256 my $status = $FACEMAP->db_get (id => $id, BerkeleyDB::DB_RMW); 1462 my $status = $FACEMAP->db_get (id => $id, BerkeleyDB::DB_RMW);
1257 if ($status == 0 || $status == BerkeleyDB::DB_NOTFOUND) { 1463 if ($status == 0 || $status == BerkeleyDB::DB_NOTFOUND) {
1258 $id++; 1464 $id = ($id || 16) + 1;
1259 if ($FACEMAP->put (id => $id) == 0 1465 if ($FACEMAP->put (id => $id) == 0
1260 && $FACEMAP->put ($hash => $id) == 0) { 1466 && $FACEMAP->put ($hash => $id) == 0) {
1261 $txn->txn_commit; 1467 $txn->txn_commit;
1262 1468
1263 goto gotid; 1469 goto gotid;
1271 1477
1272gotid: 1478gotid:
1273 $face->{id} = $id; 1479 $face->{id} = $id;
1274 $MAP->set_face ($facenum => $id); 1480 $MAP->set_face ($facenum => $id);
1275 $self->{faceid}[$facenum] = $id;#d# 1481 $self->{faceid}[$facenum] = $id;#d#
1482
1276 $TILECACHE->get ($id) 1483 $TILECACHE->get ($id) || do {
1484 my $tex = $self->{noface};
1485 $MAP->set_texture ($id, @$tex{qw(name w h s t)}, @{$tex->{minified}});
1486 undef
1487 };
1277} 1488}
1278 1489
1279sub conn::face_update { 1490sub conn::face_update {
1280 my ($self, $facenum, $face) = @_; 1491 my ($self, $facenum, $face) = @_;
1281 1492
1374 ); 1585 );
1375 1586
1376 $entry->focus_in; 1587 $entry->focus_in;
1377 } 1588 }
1378 1589
1379 $dialog->show; 1590 $dialog->show_centered;
1380} 1591}
1381 1592
1382sub conn::drawinfo { 1593sub conn::drawinfo {
1383 my ($self, $color, $text) = @_; 1594 my ($self, $color, $text) = @_;
1384 1595
1438 my ($self) = @_; 1649 my ($self) = @_;
1439 1650
1440 $self->send ("command output-sync $CFG->{output_sync}"); 1651 $self->send ("command output-sync $CFG->{output_sync}");
1441 $self->send ("command output-count $CFG->{output_count}"); 1652 $self->send ("command output-count $CFG->{output_count}");
1442 1653
1654 my $parser = new Pod::POM;
1655 my $pod = $parser->parse_file (CFClient::find_rcfile "pod/skill_help.pod");
1656
1657 my %skill_tooltip;
1658
1659 for my $head2 ($pod->head2) {
1660 $skill_tooltip{$head2->title} = CFClient::pod_to_pango $head2->content;
1661 }
1662
1443 for my $skill (values %{$self->{skill_info}}) { 1663 for my $skill (values %{$self->{skill_info}}) {
1444 $MAPWIDGET->add_command ("ready_skill $skill", CFClient::UI::Label::escape "Ready the skill '$skill'"); 1664 $MAPWIDGET->add_command ("ready_skill $skill",
1445 $MAPWIDGET->add_command ("use_skill $skill", CFClient::UI::Label::escape "Immediately use the skill '$skill'"); 1665 (CFClient::UI::Label::escape "Ready the skill '$skill'\n\n")
1666 . $skill_tooltip{$skill});
1667 $MAPWIDGET->add_command ("use_skill $skill",
1668 (CFClient::UI::Label::escape "Immediately use the skill '$skill'\n\n")
1669 . $skill_tooltip{$skill});
1446 } 1670 }
1447} 1671}
1448 1672
1449sub conn::eof { 1673sub conn::eof {
1450 $MAPWIDGET->clr_commands; 1674 $MAPWIDGET->clr_commands;
1569 Event::unloop -1; 1793 Event::unloop -1;
1570 }, 1794 },
1571 CFClient::SDL_VIDEORESIZE => sub { 1795 CFClient::SDL_VIDEORESIZE => sub {
1572 }, 1796 },
1573 CFClient::SDL_VIDEOEXPOSE => sub { 1797 CFClient::SDL_VIDEOEXPOSE => sub {
1574 $WANT_REFRESH++; 1798 CFClient::UI::full_refresh;
1575 }, 1799 },
1576 CFClient::SDL_ACTIVEEVENT => sub { 1800 CFClient::SDL_ACTIVEEVENT => sub {
1577# printf "active %x %x\n", $SDL_EV->active_gain, $SDL_EV->active_state;#d# 1801# printf "active %x %x\n", $SDL_EV->active_gain, $SDL_EV->active_state;#d#
1578 }, 1802 },
1579 CFClient::SDL_KEYDOWN => sub { 1803 CFClient::SDL_KEYDOWN => sub {
1615 sdl_mode => 0, 1839 sdl_mode => 0,
1616 width => 640, 1840 width => 640,
1617 height => 480, 1841 height => 480,
1618 fullscreen => 0, 1842 fullscreen => 0,
1619 fast => 0, 1843 fast => 0,
1620 map_scale => 0.5, 1844 map_scale => 1,
1621 fow_enable => 1, 1845 fow_enable => 1,
1622 fow_intensity => 0.45, 1846 fow_intensity => 0.45,
1623 fow_smooth => 0, 1847 fow_smooth => 0,
1624 gui_fontsize => 1, 1848 gui_fontsize => 1,
1625 log_fontsize => 1, 1849 log_fontsize => 1,
1691 1915
1692Event::loop; 1916Event::loop;
1693 1917
1694END { CFClient::SDL_Quit } 1918END { CFClient::SDL_Quit }
1695 1919
1920=head1 NAME
1921
1696=head1 pclient - Crossfire+ and Crossfire game client 1922pclient - A Crossfire+ and Crossfire game client
1697 1923
1698Pclient is a Crossfire+ and Crossfire game client. 1924=head1 SYNOPSIS
1699 1925
1700=head2 Features 1926Just run it - no commandline arguments are supported.
1701
1702=over 4
1703
1704=item Fullscreen Map
1705
1706PClient can uses a fullscreen map, which greatly enhances how much of the
1707game world you can see.
1708
1709=item Persistent Map Cache (Crossfire+ only)
1710
1711PClient can persistently cache all map data it received from the
1712server. This not only allows it to display an overview map, but also
1713ensures that once-explored areas will be available the next time you want
1714to explore more.
1715
1716=item Hardware acceleration
1717
1718Unlike most Crossfire clients, PClient take advantage of OpenGL hardware
1719acceleration. Most modern graphics cards have difficulties with 2D
1720acceleration, while 3D graphics is accelerated well.
1721
1722=item No arbitrary limits
1723
1724Unlike other Crossfire clients, pclient does not suffer from arbitrary
1725limits (like a fixed amount of face numbers). There are still limits, but
1726they are not arbitrarily low :)
1727
1728=back
1729 1927
1730=head1 USAGE 1928=head1 USAGE
1731 1929
1732=head2 The Map 1930Pclient utilises OpenGL for all UI elements and the game. It is supposed to be used
1733 1931fullscreen and interactively.
1734The map is always displayed in the background, behind all other windows and UI elements.
1735
1736#TODO# middle-click scrolls
1737#
1738# keys:
1739#
1740# a apply
1741# keypad moves, kp_5 applies ranged attack to self
1742
1743Starting to type enters the I<completion mode>. In that mode, you can type
1744abbreviations or commands and have them executed as soon as they match a
1745valid command. This is best explained by a few examples:
1746
1747Typing B<climb> will display a list of commands with I<climb> in their
1748name, such as I<ready_skill climbing> and I<use_skill climbing>.
1749
1750You can abbreviate commands by typing only the first character of every
1751word. For example, typing I<iwor> will likely select I<invoke word of
1752recall>, while I<ccfo> will select I<cast create food>. Likewise, I<rscli>
1753will likely select I<ready_skill climbing> and I<usl> will give you
1754I<use_skill levitation>.
1755
1756=head2 The map overview
1757
1758#TODO#
1759
1760=head2 The Status area in the lower right corner
1761
1762#TODO#
1763
1764=head2 The I<Statistics>/I>Stats> window
1765
1766#TODO#
1767
1768=head1 FAQ
1769
1770=over 4
1771
1772=item The client is very sluggish and slow, what can I do about this?
1773
1774Most likely, you don't have accelerated OpenGL support. Try to find a
1775newer driver, or a driver from your hardware vendor, that features OpenGL
1776support.
1777
1778If this is not an option, the following Setup options reduce the load and
1779will likely make the client playable with sofwtare rendering (it will
1780still be slow, though):
1781
1782=over 4
1783
1784=item B<Video Mode> should be set as low as possible (e.g. 640x480)
1785
1786=item Enable B<Fast & Ugly> mode
1787
1788=item Disable B<Fog of War>
1789
1790=item Increase B<Map Scale>
1791
1792=back
1793
1794=back
1795 1932
1796=head1 AUTHOR 1933=head1 AUTHOR
1797 1934
1798Marc Lehmann <crossfire@schmorp.de>, Robin Redeker <elmex@ta-sa.org> 1935Marc Lehmann <crossfire@schmorp.de>, Robin Redeker <elmex@ta-sa.org>
1799 1936

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines