… | |
… | |
36 | |
36 | |
37 | use CFClient; |
37 | use CFClient; |
38 | use CFClient::UI; |
38 | use CFClient::UI; |
39 | use CFClient::MapWidget; |
39 | use CFClient::MapWidget; |
40 | |
40 | |
41 | $SIG{__DIE__} = sub { CFClient::fatal "$_[0]"; exit 1 }; |
41 | $Event::DIED = sub { |
|
|
42 | CFClient::error $_[1]; |
|
|
43 | }; |
|
|
44 | |
|
|
45 | #$SIG{__WARN__} = sub { Carp::cluck $_[0] };#d# |
42 | |
46 | |
43 | our $VERSION = '0.1'; |
47 | our $VERSION = '0.1'; |
44 | |
48 | |
45 | my $MAX_FPS = 60; |
49 | my $MAX_FPS = 60; |
46 | my $MIN_FPS = 5; # unused as of yet |
50 | my $MIN_FPS = 5; # unused as of yet |
… | |
… | |
555 | $vbox->add ($dialog->{table} = new CFClient::UI::Table); |
559 | $vbox->add ($dialog->{table} = new CFClient::UI::Table); |
556 | |
560 | |
557 | $dialog |
561 | $dialog |
558 | } |
562 | } |
559 | |
563 | |
|
|
564 | my $METASERVER_ATIME; |
|
|
565 | |
560 | sub update_metaserver { |
566 | sub update_metaserver { |
561 | my ($HOST) = @_; |
567 | my ($HOST) = @_; |
562 | |
568 | |
563 | status "fetching metaserver list..."; |
569 | return if $METASERVER_ATIME > time; |
|
|
570 | $METASERVER_ATIME = time + 60; |
|
|
571 | |
|
|
572 | my $table = $METASERVER->{table}; |
|
|
573 | $table->clear; |
|
|
574 | $table->add (0, 0, my $label = new CFClient::UI::Label max_w => $WIDTH * 0.8, text => "fetching server list..."); |
564 | |
575 | |
565 | my $buf; |
576 | my $buf; |
566 | |
577 | |
567 | my $fh = new IO::Socket::INET PeerHost => $META_SERVER, Blocking => 0; |
578 | my $fh = new IO::Socket::INET PeerHost => $META_SERVER, Blocking => 0; |
|
|
579 | |
|
|
580 | unless ($fh) { |
|
|
581 | $label->set_text ("unable to contact metaserver: $!"); |
|
|
582 | return; |
|
|
583 | } |
568 | |
584 | |
569 | Event->io (fd => $fh, poll => 'r', cb => sub { |
585 | Event->io (fd => $fh, poll => 'r', cb => sub { |
570 | my $res = sysread $fh, $buf, 8192, length $buf; |
586 | my $res = sysread $fh, $buf, 8192, length $buf; |
571 | |
587 | |
572 | if (!defined $res) { |
588 | if (!defined $res) { |
573 | $_[0]->w->cancel; |
589 | $_[0]->w->cancel; |
574 | status "metaserver: $!"; |
590 | $label->set_text ("error while retrieving server list: $!"); |
575 | } elsif ($res == 0) { |
591 | } elsif ($res == 0) { |
576 | $_[0]->w->cancel; |
592 | $_[0]->w->cancel; |
577 | status "server list retrieved"; |
593 | status "server list retrieved"; |
578 | |
594 | |
579 | my $table = $METASERVER->{table}; |
595 | utf8::decode $buf if utf8::valid $buf; |
580 | |
596 | |
581 | $table->clear; |
597 | $table->clear; |
582 | |
598 | |
583 | my @col = qw(Use #Users Host Uptime Version Description); |
599 | my @col = qw(Use #Users Host Uptime Version Description); |
584 | $table->add ($_, 0, new CFClient::UI::Label align => 0, fg => [1, 1, 0], text => $col[$_]) |
600 | $table->add ($_, 0, new CFClient::UI::Label align => 0, fg => [1, 1, 0], text => $col[$_]) |
… | |
… | |
608 | $m = [$users, $host, $uptime, $version, $desc]; |
624 | $m = [$users, $host, $uptime, $version, $desc]; |
609 | |
625 | |
610 | $y++; |
626 | $y++; |
611 | |
627 | |
612 | $table->add (0, $y, new CFClient::UI::VBox children => [ |
628 | $table->add (0, $y, new CFClient::UI::VBox children => [ |
613 | (new CFClient::UI::Button text => " ", connect_activate => sub { |
629 | (new CFClient::UI::Button text => "Use", connect_activate => sub { |
614 | $HOST->set_text ($CFG->{host} = $host); |
630 | $HOST->set_text ($CFG->{host} = $host); |
615 | }), |
631 | }), |
616 | (new CFClient::UI::Empty expand => 1), |
632 | (new CFClient::UI::Empty expand => 1), |
617 | ]); |
633 | ]); |
618 | |
634 | |
… | |
… | |
837 | $BUTTONBAR->{children}[1]->emit ("activate"); # pop up server setup |
853 | $BUTTONBAR->{children}[1]->emit ("activate"); # pop up server setup |
838 | } |
854 | } |
839 | |
855 | |
840 | sub video_shutdown { |
856 | sub video_shutdown { |
841 | $CFClient::UI::ROOT->{children} = []; |
857 | $CFClient::UI::ROOT->{children} = []; |
|
|
858 | undef $CFClient::UI::GRAB; |
|
|
859 | undef $CFClient::UI::HOVER; |
842 | undef $SDL_ACTIVE; |
860 | undef $SDL_ACTIVE; |
843 | } |
861 | } |
844 | |
862 | |
845 | my @bgmusic = qw(game1.ogg game2.ogg game3.ogg game5.ogg game6.ogg ross1.ogg ross2.ogg ross3.ogg ross4.ogg ross5.ogg); #d# |
863 | my @bgmusic = qw(game1.ogg game2.ogg game3.ogg game5.ogg game6.ogg ross1.ogg ross2.ogg ross3.ogg ross4.ogg ross5.ogg); #d# |
846 | my $bgmusic;#TODO#hack#d# |
864 | my $bgmusic;#TODO#hack#d# |
… | |
… | |
1460 | |
1478 | |
1461 | Event::loop; |
1479 | Event::loop; |
1462 | |
1480 | |
1463 | END { CFClient::SDL_Quit } |
1481 | END { CFClient::SDL_Quit } |
1464 | |
1482 | |
|
|
1483 | =head1 pclient - Crossfire+ and Crossfire game client |
1465 | |
1484 | |
|
|
1485 | Pclient is a Crossfire+ and Crossfire game client. |
|
|
1486 | |
|
|
1487 | =head2 Features |
|
|
1488 | |
|
|
1489 | =over 4 |
|
|
1490 | |
|
|
1491 | =item Fullscreen Map |
|
|
1492 | |
|
|
1493 | PClient can uses a fullscreen map, which greatly enhances how much of the |
|
|
1494 | game world you can see. |
|
|
1495 | |
|
|
1496 | =item Persistent Map Cache (Crossfire+ only) |
|
|
1497 | |
|
|
1498 | PClient can persistently cache all map data it received from the |
|
|
1499 | server. This not only allows it to display an overview map, but also |
|
|
1500 | ensures that once-explored areas will be available the next time you want |
|
|
1501 | to explore more. |
|
|
1502 | |
|
|
1503 | =item Hardware acceleration |
|
|
1504 | |
|
|
1505 | Unlike most Crossfire clients, PClient take advantage of OpenGL hardware |
|
|
1506 | acceleration. Most modern graphics cards have difficulties with 2D |
|
|
1507 | acceleration, while 3D graphics is accelerated well. |
|
|
1508 | |
|
|
1509 | =item No arbitrary limits |
|
|
1510 | |
|
|
1511 | Unlike other Crossfire clients, pclient does not suffer from arbitrary |
|
|
1512 | limits (like a fixed amount of face numbers). There are still limits, but |
|
|
1513 | they are not arbitrarily low :) |
|
|
1514 | |
|
|
1515 | =back |
|
|
1516 | |
|
|
1517 | =head1 USAGE |
|
|
1518 | |
|
|
1519 | =head2 The Map |
|
|
1520 | |
|
|
1521 | The map is always displayed in the background, behind all other windows and UI elements. |
|
|
1522 | |
|
|
1523 | #TODO# middle-click scrolls |
|
|
1524 | # |
|
|
1525 | # keys: |
|
|
1526 | # |
|
|
1527 | # a apply |
|
|
1528 | # keypad moves, kp_5 applies ranged attack to self |
|
|
1529 | |
|
|
1530 | Starting to type enters the I<completion mode>. In that mode, you can type |
|
|
1531 | abbreviations or commands and have them executed as soon as they match a |
|
|
1532 | valid command. This is best explained by a few examples: |
|
|
1533 | |
|
|
1534 | Typing B<climb> will display a list of commands with I<climb> in their |
|
|
1535 | name, such as I<ready_skill climbing> and I<use_skill climbing>. |
|
|
1536 | |
|
|
1537 | You can abbreviate commands by typing only the first character of every |
|
|
1538 | word. For example, typing I<iwor> will likely select I<invoke word of |
|
|
1539 | recall>, while I<ccfo> will select I<cast create food>. Likewise, I<rscli> |
|
|
1540 | will likely select I<ready_skill climbing> and I<usl> will give you |
|
|
1541 | I<use_skill levitation>. |
|
|
1542 | |
|
|
1543 | =head2 The map overview |
|
|
1544 | |
|
|
1545 | #TODO# |
|
|
1546 | |
|
|
1547 | =head2 The Status area in the lower right corner |
|
|
1548 | |
|
|
1549 | #TODO# |
|
|
1550 | |
|
|
1551 | =head2 The I<Statistics>/I>Stats> window |
|
|
1552 | |
|
|
1553 | #TODO# |
|
|
1554 | |
|
|
1555 | =head1 FAQ |
|
|
1556 | |
|
|
1557 | =over 4 |
|
|
1558 | |
|
|
1559 | =item The client is very sluggish and slow, what can I do about this? |
|
|
1560 | |
|
|
1561 | Most likely, you don't have accelerated OpenGL support. Try to find a |
|
|
1562 | newer driver, or a driver from your hardware vendor, that features OpenGL |
|
|
1563 | support. |
|
|
1564 | |
|
|
1565 | If this is not an option, the following Setup options reduce the load and |
|
|
1566 | will likely make the client playable with sofwtare rendering (it will |
|
|
1567 | still be slow, though): |
|
|
1568 | |
|
|
1569 | =over 4 |
|
|
1570 | |
|
|
1571 | =item B<Video Mode> should be set as low as possible (e.g. 640x480) |
|
|
1572 | |
|
|
1573 | =item Enable B<Fast & Ugly> mode |
|
|
1574 | |
|
|
1575 | =item Disable B<Fog of War> |
|
|
1576 | |
|
|
1577 | =item Increase B<Map Scale> |
|
|
1578 | |
|
|
1579 | =back |
|
|
1580 | |
|
|
1581 | =back |
|
|
1582 | |
|
|
1583 | =head1 AUTHOR |
|
|
1584 | |
|
|
1585 | Marc Lehmann <crossfire@schmorp.de>, Robin Redeker <elmex@ta-sa.org> |
|
|
1586 | |
|
|
1587 | |
|
|
1588 | |