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.216 by root, Mon May 15 17:45:31 2006 UTC vs.
Revision 1.232 by root, Sun May 21 00:35:00 2006 UTC

1#!/opt/bin/perl 1#!/opt/bin/perl
2 2
3use strict; 3use strict;
4use utf8; 4use utf8;
5 5
6# do things only needed for single-binary version (par)
6BEGIN { 7BEGIN {
7 if (%PAR::LibCache) { 8 if (%PAR::LibCache) {
8 @INC = grep ref, @INC; # weed out all paths except pars loader refs 9 @INC = grep ref, @INC; # weed out all paths except pars loader refs
9 10
10 while (my ($filename, $zip) = each %PAR::LibCache) { 11 while (my ($filename, $zip) = each %PAR::LibCache) {
13 $zip->extractMember ($_, "$ENV{PAR_TEMP}/$1") 14 $zip->extractMember ($_, "$ENV{PAR_TEMP}/$1")
14 unless -e "$ENV{PAR_TEMP}/$1"; 15 unless -e "$ENV{PAR_TEMP}/$1";
15 } 16 }
16 } 17 }
17 18
19 # TODO: pango-rc file, anybody?
20
18 unshift @INC, $ENV{PAR_TEMP}; 21 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 } 22 }
24} 23}
25 24
26# need to do it again because that pile of garbage called PAR nukes it before main 25# need to do it again because that pile of garbage called PAR nukes it before main
27unshift @INC, $ENV{PAR_TEMP}; 26unshift @INC, $ENV{PAR_TEMP}
27 if %PAR::LibCache;
28 28
29use Time::HiRes 'time'; 29use Time::HiRes 'time';
30use Pod::POM;
30use Event; 31use Event;
31 32
32use Crossfire; 33use Crossfire;
33use Crossfire::Protocol; 34use Crossfire::Protocol;
34 35
99our $STATUSBOX; 100our $STATUSBOX;
100our $DEBUG_STATUS; 101our $DEBUG_STATUS;
101 102
102our $INVWIN; 103our $INVWIN;
103our $INV; 104our $INV;
105our $INVR;
106our $INVR_LBL;
107our $OPENCONT;
104 108
105sub status { 109sub status {
106 $STATUSBOX->add ($_[0], pri => -10, group => "status", timeout => 20, fg => [1, 1, 0, 1]); 110 $STATUSBOX->add (CFClient::UI::Label::escape $_[0], pri => -10, group => "status", timeout => 20, fg => [1, 1, 0, 1]);
107} 111}
108 112
109sub debug { 113sub debug {
110 $DEBUG_STATUS->set_text ($_[0]); 114 $DEBUG_STATUS->set_text ($_[0]);
111 my ($w, $h) = $DEBUG_STATUS->size_request; 115 my ($w, $h) = $DEBUG_STATUS->size_request;
132 maph => $mapsize, 136 maph => $mapsize,
133 ; 137 ;
134 }; 138 };
135 139
136 if ($CONN) { 140 if ($CONN) {
141 CFClient::lowdelay fileno $CONN->{fh};
142
137 $LOGIN_BUTTON->set_text ("Logout"); 143 $LOGIN_BUTTON->set_text ("Logout");
138
139 status "login successful"; 144 status "login successful";
140 145
141 CFClient::lowdelay fileno $CONN->{fh}; 146 $BUTTONBAR->{children}[1]->emit ("activate")
147 if $BUTTONBAR->{children}[1]->{state};
148
142 } else { 149 } else {
143 status "unable to connect"; 150 status "unable to connect";
144 stop_game(); 151 stop_game();
145 } 152 }
146} 153}
150 157
151 status "connection closed"; 158 status "connection closed";
152 $LOGIN_BUTTON->set_text ("Login"); 159 $LOGIN_BUTTON->set_text ("Login");
153 $CONN->destroy; 160 $CONN->destroy;
154 $CONN = 0; # false, does not autovivify 161 $CONN = 0; # false, does not autovivify
162
163 $BUTTONBAR->{children}[1]->emit ("activate")
164 unless $BUTTONBAR->{children}[1]->{state};
155 165
156 undef $MAPCACHE; 166 undef $MAPCACHE;
157 undef $MAP; 167 undef $MAP;
158} 168}
159 169
663 $HOST->set_text ($CFG->{host} = $host); 673 $HOST->set_text ($CFG->{host} = $host);
664 }), 674 }),
665 (new CFClient::UI::Empty expand => 1), 675 (new CFClient::UI::Empty expand => 1),
666 ]); 676 ]);
667 677
668 $table->add ($_ + 1, $y, new CFClient::UI::Label align => $align[$_], text => $m->[$_], fontsize => 0.8) 678 $table->add ($_ + 1, $y, new CFClient::UI::Label
679 ellipsise => 0, align => $align[$_], text => $m->[$_], fontsize => 0.8)
669 for 0 .. $#$m; 680 for 0 .. $#$m;
670 } 681 }
671 } 682 }
672 }); 683 });
673} 684}
739 750
740 $CFG->{mapsize} = $self->{range}[0] = $value = int $value; 751 $CFG->{mapsize} = $self->{range}[0] = $value = int $value;
741 }, 752 },
742 ); 753 );
743 754
755 $table->add (0, 8, new CFClient::UI::Label valign => 0, align => 1, text => "Output-Count");
756 $table->add (1, 8, new CFClient::UI::Entry
757 text => $CFG->{output_count},
758 tooltip => "Should be set to 1 unless you know what you are doing",
759 connect_changed => sub { $CFG->{output_count} = $_[1] },
760 );
761
762 $table->add (0, 9, new CFClient::UI::Label valign => 0, align => 1, text => "Output-Sync");
763 $table->add (1, 9, new CFClient::UI::Entry
764 text => $CFG->{output_sync},
765 tooltip => "Should be set to 1 unless you know what you are doing",
766 connect_changed => sub { $CFG->{output_sync} = $_[1] },
767 );
768
744 $table->add (1, 8, $LOGIN_BUTTON = new CFClient::UI::Button 769 $table->add (1, 10, $LOGIN_BUTTON = new CFClient::UI::Button
745 expand => 1, 770 expand => 1,
746 align => 0, 771 align => 0,
747 text => "Login", 772 text => "Login",
748 connect_activate => sub { 773 connect_activate => sub {
749 $CONN ? stop_game 774 $CONN ? stop_game
761 bg => [0, 0, 0, 0.5], 786 bg => [0, 0, 0, 0.5],
762 user_w => int $::WIDTH / 3, 787 user_w => int $::WIDTH / 3,
763 user_h => int $::HEIGHT / 5, 788 user_h => int $::HEIGHT / 5,
764 child => (my $vbox = new CFClient::UI::VBox); 789 child => (my $vbox = new CFClient::UI::VBox);
765 790
766 $vbox->add ($LOGVIEW = new CFClient::UI::TextView 791 $vbox->add ($LOGVIEW);
767 expand => 1,
768 font => $FONT_FIXED,
769 fontsize => $::CFG->{log_fontsize},
770 );
771 792
772 $vbox->add (my $input = new CFClient::UI::Entry 793 $vbox->add (my $input = new CFClient::UI::Entry
773 connect_focus_in => sub { 794 connect_focus_in => sub {
774 my ($input, $prev_focus) = @_; 795 my ($input, $prev_focus) = @_;
775 796
807 828
808 $window 829 $window
809} 830}
810 831
811sub make_inventory_window { 832sub make_inventory_window {
812 my $invwin = new CFClient::UI::FancyFrame user_w => 300, user_h => 300, title => "Inventory"; 833 my $invwin = new CFClient::UI::FancyFrame
834 user_w => $WIDTH * (4/5), user_h => $HEIGHT * (4/5), title => "Inventory";
835
836 $invwin->add (my $hb = new CFClient::UI::HBox expand => 1);
837
838 $hb->add (my $vb1 = new CFClient::UI::VBox expand => 1);
839 $vb1->add (my $lbl = new CFClient::UI::Label);
840 $lbl->set_text ("Player");
813 $invwin->add ($INV = new CFClient::UI::Inventory expand => 1); 841 $vb1->add ($INV = new CFClient::UI::Inventory expand => 1);
842
843 $hb->add (my $vb2 = new CFClient::UI::VBox expand => 1);
844 $vb2->add ($INVR_LBL = new CFClient::UI::Label);
845 $INVR_LBL->set_text ("Floor");
846 $vb2->add ($INVR = new CFClient::UI::Inventory expand => 1);
847
814 $invwin 848 $invwin
815} 849}
816 850
817sub sdl_init { 851sub sdl_init {
818 CFClient::SDL_Init 852 CFClient::SDL_Init
827 ($WIDTH, $HEIGHT) = @{ $SDL_MODES[$CFG->{sdl_mode}] }; 861 ($WIDTH, $HEIGHT) = @{ $SDL_MODES[$CFG->{sdl_mode}] };
828 $FULLSCREEN = $CFG->{fullscreen}; 862 $FULLSCREEN = $CFG->{fullscreen};
829 $FAST = $CFG->{fast}; 863 $FAST = $CFG->{fast};
830 864
831 CFClient::SDL_SetVideoMode $WIDTH, $HEIGHT, $FULLSCREEN 865 CFClient::SDL_SetVideoMode $WIDTH, $HEIGHT, $FULLSCREEN
832 or die "SDL_SetVideoMode failed!\n"; 866 or die "SDL_SetVideoMode failed: " . (CFClient::SDL_GetError) . "\n";
833 867
834 $SDL_ACTIVE = 1; 868 $SDL_ACTIVE = 1;
835 $LAST_REFRESH = time - 0.01; 869 $LAST_REFRESH = time - 0.01;
836 870
837 CFClient::gl_init; 871 CFClient::gl_init;
877 } 911 }
878 }); 912 });
879 $MAPWIDGET->show; 913 $MAPWIDGET->show;
880 $MAPWIDGET->focus_in; 914 $MAPWIDGET->focus_in;
881 915
916 $LOGVIEW = new CFClient::UI::TextView
917 expand => 1,
918 font => $FONT_FIXED,
919 fontsize => $::CFG->{log_fontsize},
920 ;
921
882 $BUTTONBAR = new CFClient::UI::HBox; 922 $BUTTONBAR = new CFClient::UI::HBox;
883 923
884 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Client Setup", other => client_setup); 924 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Client Setup", other => client_setup);
885 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Server Setup", other => server_setup); 925 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Server Setup", other => server_setup);
886 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Message Window", other => message_window); 926 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Message Window", other => message_window);
917my $bgmusic;#TODO#hack#d# 957my $bgmusic;#TODO#hack#d#
918 958
919sub audio_channel_finished { 959sub audio_channel_finished {
920 my ($channel) = @_; 960 my ($channel) = @_;
921 961
922 warn "channel $channel finished\n";#d# 962 #warn "channel $channel finished\n";#d#
923} 963}
924 964
925sub audio_music_finished { 965sub audio_music_finished {
926 return unless $CFG->{bgm_enable}; 966 return unless $CFG->{bgm_enable};
927 967
971my %animate_object; 1011my %animate_object;
972my $animate_timer; 1012my $animate_timer;
973 1013
974my $fps = 9; 1014my $fps = 9;
975 1015
1016my %demo;#d#
1017
976sub force_refresh { 1018sub force_refresh {
977 $fps = $fps * 0.95 + 1 / (($NOW - $LAST_REFRESH) || 0.1) * 0.05; 1019 $fps = $fps * 0.95 + 1 / (($NOW - $LAST_REFRESH) || 0.1) * 0.05;
978 debug sprintf "%3.2f", $fps; 1020 debug sprintf "%3.2f", $fps;
979 1021
980 $CFClient::UI::ROOT->draw; 1022 $CFClient::UI::ROOT->draw;
981 CFClient::SDL_GL_SwapBuffers;
982 1023
983 $WANT_REFRESH = 0; 1024 $WANT_REFRESH = 0;
984 $CAN_REFRESH = 0; 1025 $CAN_REFRESH = 0;
985 $LAST_REFRESH = $NOW; 1026 $LAST_REFRESH = $NOW;
1027
10280 && do {
1029 # some weird model-drawing code, just a joke right now
1030 use CFClient::OpenGL;
1031
1032 $demo{t}{eye_auv} ||= new_from_file CFClient::Texture "eye2.png" or die;
1033 $demo{t}{body_auv} ||= new_from_file CFClient::Texture "body_auv3.png" or die;
1034 $demo{r} ||= do {
1035 my $mod = Compress::LZF::sthaw do { local $/; open my $fh, "<:raw:perlio", "dread.lz3"; <$fh> };
1036 $mod->{v} = pack "f*", @{$mod->{v}};
1037 $_ = [scalar @$_, pack "S!*", @$_]
1038 for values %{$mod->{g}};
1039 $mod
1040 };
1041
1042 my $r = $demo{r} or die;
1043
1044 glDepthMask 1;
1045 glClear GL_DEPTH_BUFFER_BIT;
1046 glEnable GL_TEXTURE_2D;
1047 glEnable GL_DEPTH_TEST;
1048 glDisable GL_CULL_FACE;
1049 glShadeModel $::FAST ? GL_FLAT : GL_SMOOTH;
1050
1051 glMatrixMode GL_PROJECTION;
1052 glLoadIdentity;
1053 #glFrustum -100, 100, 100, -100, 1, 1000;
1054 glOrtho 0, $::WIDTH, 0, $::HEIGHT, -10000, 10000;
1055 glMatrixMode GL_MODELVIEW;
1056 glLoadIdentity;
1057
1058 glPushMatrix;
1059 glTranslate $::WIDTH * 0.5, $::HEIGHT * 0.5, -100;
1060 glRotate $NOW * 1000 % 36000 / 20, 0, 1, 0;
1061 glScale 50, 50, 50;
1062
1063 glInterleavedArrays GL_T2F_N3F_V3F, 0, $r->{v};
1064 while (my ($k, $v) = each %{$r->{g}}) {
1065 glBindTexture GL_TEXTURE_2D, ($demo{t}{$k}{name} or die);
1066 glDrawElements GL_TRIANGLES, $v->[0], GL_UNSIGNED_SHORT, $v->[1];
1067 }
1068
1069 glPopMatrix;
1070
1071 glShadeModel GL_FLAT;
1072 glDisable GL_DEPTH_TEST;
1073 glDisable GL_TEXTURE_2D;
1074 glDepthMask 0;
1075
1076 $WANT_REFRESH++;
1077};
1078
1079 CFClient::SDL_GL_SwapBuffers;
986} 1080}
987 1081
988my $refresh_watcher = Event->timer (after => 0, hard => 1, interval => 1 / $MAX_FPS, cb => sub { 1082my $refresh_watcher = Event->timer (after => 0, hard => 1, interval => 1 / $MAX_FPS, cb => sub {
989 $NOW = time; 1083 $NOW = time;
990 1084
1013 delete $animate_object{$widget}; 1107 delete $animate_object{$widget};
1014} 1108}
1015 1109
1016@conn::ISA = Crossfire::Protocol::; 1110@conn::ISA = Crossfire::Protocol::;
1017 1111
1112sub conn::new {
1113 my $class = shift;
1114
1115 my $self = $class->Crossfire::Protocol::new (@_);
1116
1117 $MAPWIDGET->clr_commands;
1118
1119 my $parser = new Pod::POM;
1120 my $pod = $parser->parse_file (CFClient::find_rcfile "pod/command_help.pod");
1121
1122 for my $head2 ($pod->head2) {
1123 $head2->title =~ /^(\S+) (?:\s+ \( ([^\)]*) \) )?/x
1124 or next;
1125
1126 my $cmd = $1;
1127 my @args = split /\|/, $2;
1128 @args = (".*") unless @args;
1129
1130 my $text = CFClient::pod_to_pango $head2->content;
1131
1132 for my $arg (@args) {
1133 $arg = $arg eq ".*" ? "" : " $arg";
1134
1135 $MAPWIDGET->add_command ("$cmd$arg", $text);
1136 }
1137 }
1138
1139 $self
1140}
1141
1018sub conn::stats_update { 1142sub conn::stats_update {
1019 my ($self, $stats) = @_; 1143 my ($self, $stats) = @_;
1144
1145 if (my $exp = $stats->{Crossfire::Protocol::CS_STAT_EXP64}) {
1146 my $diff = $exp - $self->{prev_exp};
1147 $STATUSBOX->add ("$diff experience gained", group => "experience $diff", fg => [0.5, 1, 0.5, 0.8], timeout => 5)
1148 if exists $self->{prev_exp} && $diff;
1149 $self->{prev_exp} = $exp;
1150 }
1020 1151
1021 update_stats_window ($stats); 1152 update_stats_window ($stats);
1022} 1153}
1023 1154
1024sub conn::user_send { 1155sub conn::user_send {
1323 [0.74, 0.65, 0.41], 1454 [0.74, 0.65, 0.41],
1324 ); 1455 );
1325 1456
1326 my $time = sprintf "%02d:%02d:%02d", (localtime time)[2,1,0]; 1457 my $time = sprintf "%02d:%02d:%02d", (localtime time)[2,1,0];
1327 1458
1328 $text =~ s/&/&amp;/g; $text =~ s/</&lt;/g; 1459 $text = CFClient::UI::Label::escape $text;
1329 $text =~ s/\[b\](.*?)\[\/b\]/<b>\1<\/b>/g; 1460 $text =~ s/\[b\](.*?)\[\/b\]/<b>\1<\/b>/g;
1330 $text =~ s/\[color=(.*?)\](.*?)\[\/color\]/<span foreground='\1'>\2<\/span>/g; 1461 $text =~ s/\[color=(.*?)\](.*?)\[\/color\]/<span foreground='\1'>\2<\/span>/g;
1331 1462
1332 $LOGVIEW->add_paragraph ($color[$color], 1463 $LOGVIEW->add_paragraph ($color[$color],
1333 join "\n", map "$time $_", split /\n/, $text); 1464 join "\n", map "$time $_", split /\n/, $text);
1349sub conn::spell_add { 1480sub conn::spell_add {
1350 my ($self, $spell) = @_; 1481 my ($self, $spell) = @_;
1351 1482
1352 # TODO 1483 # TODO
1353 # create a widget dynamically, using spell face (CF::Protocol downloads them) 1484 # create a widget dynamically, using spell face (CF::Protocol downloads them)
1354 $MAPWIDGET->add_command ("invoke $spell->{name}", $spell->{message}); 1485 $MAPWIDGET->add_command ("invoke $spell->{name}", CFClient::UI::Label::escape $spell->{message});
1355 $MAPWIDGET->add_command ("cast $spell->{name}", $spell->{message}); 1486 $MAPWIDGET->add_command ("cast $spell->{name}", CFClient::UI::Label::escape $spell->{message});
1356} 1487}
1357 1488
1358sub conn::spell_delete { 1489sub conn::spell_delete {
1359 my ($self, $spell) = @_; 1490 my ($self, $spell) = @_;
1360} 1491}
1361 1492
1362sub conn::addme_success { 1493sub conn::addme_success {
1363 my ($self) = @_; 1494 my ($self) = @_;
1364 1495
1496 $self->send ("command output-sync $CFG->{output_sync}");
1497 $self->send ("command output-count $CFG->{output_count}");
1498
1365 for my $skill (values %{$self->{skill_info}}) { 1499 for my $skill (values %{$self->{skill_info}}) {
1366 $MAPWIDGET->add_command ("ready_skill $skill", "Ready the skill '$skill'"); 1500 $MAPWIDGET->add_command ("ready_skill $skill", CFClient::UI::Label::escape "Ready the skill '$skill'");
1367 $MAPWIDGET->add_command ("use_skill $skill", "Immediately use the skill '$skill'"); 1501 $MAPWIDGET->add_command ("use_skill $skill", CFClient::UI::Label::escape "Immediately use the skill '$skill'");
1368 } 1502 }
1369
1370 $MAPWIDGET->add_command ("pet\\_mode defend", "Tell pets to stay close to you and defend you");
1371 $MAPWIDGET->add_command ("pet\\_mode arena", "Same as petmode attack, but also attack other players");
1372 $MAPWIDGET->add_command ("pet\\_mode sad", "Search &amp; Destroy - tell pets to roam about and attack enemies");
1373 $MAPWIDGET->add_command ("kill\\_pets", "kill your pets");
1374} 1503}
1375 1504
1376sub conn::eof { 1505sub conn::eof {
1506 $MAPWIDGET->clr_commands;
1507
1377 stop_game; 1508 stop_game;
1378} 1509}
1379 1510
1380sub update_floorbox { 1511sub update_floorbox {
1381 $CFClient::UI::ROOT->on_refresh ($FLOORBOX => sub { 1512 $CFClient::UI::ROOT->on_refresh ($FLOORBOX => sub {
1399} 1530}
1400 1531
1401sub conn::container_add { 1532sub conn::container_add {
1402 my ($self, $tag, $items) = @_; 1533 my ($self, $tag, $items) = @_;
1403 1534
1404 update_floorbox if $tag == 0; 1535 #d# print "container_add: container $tag ($self->{player}{tag})\n";
1405 1536
1537 if ($tag == 0) {
1538 update_floorbox;
1539 $OPENCONT = 0;
1540 $INVR_LBL->set_text ("Floor");
1541 $INVR->set_items ($self->{container}{0});
1542 } elsif ($tag == $self->{player}{tag}) {
1543 $INVR_LBL->set_text ("Player");
1406 $INV->set_items ($self->{container}{$self->{player}{tag}}) 1544 $INV->set_items ($self->{container}{$self->{player}{tag}})
1407 if $tag == $self->{player}{tag}; 1545 } else {
1546 $OPENCONT = $tag;
1547 $INVR_LBL->set_text (CFClient::UI::InventoryItem::_item_to_desc ($self->{item}->{$OPENCONT}));
1548 $INVR->set_items ($self->{container}{$tag});
1549 }
1408 1550
1409 # $self-<{player}{tag} => player inv 1551 # $self-<{player}{tag} => player inv
1410 #use PApp::Util; warn PApp::Util::dumpval $self->{container}{$self->{player}{tag}}; 1552 #use PApp::Util; warn PApp::Util::dumpval $self->{container}{$self->{player}{tag}};
1411} 1553}
1412 1554
1413sub conn::container_clear { 1555sub conn::container_clear {
1414 my ($self, $tag) = @_; 1556 my ($self, $tag) = @_;
1415 1557
1416 update_floorbox if $tag == 0; 1558 #d# print "container_clear: container $tag ($self->{player}{tag})\n";
1417 1559
1560 if ($tag == 0) {
1561 update_floorbox;
1562 $OPENCONT = 0;
1563 $INVR_LBL->set_text ("Floor");
1564 $INVR->set_items ($self->{container}{0});
1565 } elsif ($tag == $self->{player}{tag}) {
1566 $INVR_LBL->set_text ("Player");
1418 $INV->set_items ($self->{container}{$tag}) 1567 $INV->set_items ($self->{container}{$tag})
1419 if $tag == $self->{player}{tag}; 1568 } else {
1569 $OPENCONT = $tag;
1570 $INVR_LBL->set_text (CFClient::UI::InventoryItem::_item_to_desc ($self->{item}->{$OPENCONT}));
1571 $INVR->set_items ($self->{container}{$tag});
1572 }
1420 1573
1421# use PApp::Util; warn PApp::Util::dumpval $self->{container}{0}; 1574# use PApp::Util; warn PApp::Util::dumpval $self->{container}{0};
1422} 1575}
1423 1576
1424sub conn::item_delete { 1577sub conn::item_delete {
1425 my ($self, @items) = @_; 1578 my ($self, @items) = @_;
1426 1579
1427 for (@items) { 1580 for (@items) {
1428 update_floorbox if $_->{container} == 0; 1581 #d# print "item_delete: $_->{tag} from $_->{container} ($self->{player}{tag})\n";
1429 1582
1583 if ($_->{container} == 0) {
1584 update_floorbox;
1585 $OPENCONT = 0;
1586 $INVR_LBL->set_text ("Floor");
1587 $INVR->set_items ($self->{container}{0});
1588 } elsif ($_->{container} == $self->{player}{tag}) {
1589 $INVR_LBL->set_text ("Player");
1590 $INV->set_items ($self->{container}{$self->{player}{tag}})
1591 } else {
1592 $OPENCONT = $_->{container};
1593 $INVR_LBL->set_text (CFClient::UI::InventoryItem::_item_to_desc ($self->{item}->{$OPENCONT}));
1430 $INV->set_items ($self->{container}{$_->{container}}) 1594 $INVR->set_items ($self->{container}{$_->{container}});
1431 if $_->{container} == $self->{player}{tag}; 1595 }
1432 } 1596 }
1433} 1597}
1434 1598
1435sub conn::item_update { 1599sub conn::item_update {
1436 my ($self, $item) = @_; 1600 my ($self, $item) = @_;
1437 1601
1438 update_floorbox if $item->{container} == 0; 1602 #d# print "item_update: $item->{tag} in $item->{container} ($self->{player}{tag}) ($OPENCONT)\n";
1439 1603
1604 if ($item->{tag} == $OPENCONT && not ($item->{flags} & Crossfire::Protocol::F_OPEN)) {
1605 $OPENCONT = 0;
1606 $INVR_LBL->set_text ("Floor");
1607 $INVR->set_items ($self->{container}{0});
1608
1609 $item->{widget}->update_item
1610 if $item->{widget};
1611 } else {
1612 if ($item->{container} == 0) {
1613 update_floorbox;
1614 $OPENCONT = 0;
1615 $INVR_LBL->set_text ("Floor");
1616 $INVR->set_items ($self->{container}{0});
1617 } elsif ($item->{container} == $self->{player}{tag}) {
1440 $INV->set_items ($self->{container}{$item->{container}}) 1618 $INV->set_items ($self->{container}{$item->{container}})
1441 if $item->{container} == $self->{player}{tag}; 1619 }
1620 }
1442} 1621}
1443 1622
1444%SDL_CB = ( 1623%SDL_CB = (
1445 CFClient::SDL_QUIT => sub { 1624 CFClient::SDL_QUIT => sub {
1446 Event::unloop -1; 1625 Event::unloop -1;
1492 sdl_mode => 0, 1671 sdl_mode => 0,
1493 width => 640, 1672 width => 640,
1494 height => 480, 1673 height => 480,
1495 fullscreen => 0, 1674 fullscreen => 0,
1496 fast => 0, 1675 fast => 0,
1497 map_scale => 0.5, 1676 map_scale => 1,
1498 fow_enable => 1, 1677 fow_enable => 1,
1499 fow_intensity => 0.45, 1678 fow_intensity => 0.45,
1500 fow_smooth => 0, 1679 fow_smooth => 0,
1501 gui_fontsize => 1, 1680 gui_fontsize => 1,
1502 log_fontsize => 1, 1681 log_fontsize => 1,
1507 host => "crossfire.schmorp.de", 1686 host => "crossfire.schmorp.de",
1508 say_command => 'say', 1687 say_command => 'say',
1509 audio_enable => 1, 1688 audio_enable => 1,
1510 bgm_enable => 1, 1689 bgm_enable => 1,
1511 bgm_volume => 0.25, 1690 bgm_volume => 0.25,
1691 output_sync => 1,
1692 output_count => 1,
1512 ); 1693 );
1513 1694
1514 while (my ($k, $v) = each %DEF_CFG) { 1695 while (my ($k, $v) = each %DEF_CFG) {
1515 $CFG->{$k} = $v unless exists $CFG->{$k}; 1696 $CFG->{$k} = $v unless exists $CFG->{$k};
1516 } 1697 }
1545 $FONT_FIXED = new_from_file CFClient::Font $fonts[1]; 1726 $FONT_FIXED = new_from_file CFClient::Font $fonts[1];
1546 1727
1547 $FONT_PROP->make_default; 1728 $FONT_PROP->make_default;
1548 } 1729 }
1549 1730
1731# compare mono (ft) vs. rgba (cairo)
1732# ft - 1.8s, cairo 3s, even in alpha-only mode
1733# for my $rgba (0..1) {
1734# my $t1 = Time::HiRes::time;
1735# for (1..1000) {
1736# my $layout = CFClient::Layout->new ($rgba);
1737# $layout->set_text ("hallo" x 100);
1738# $layout->render;
1739# }
1740# my $t2 = Time::HiRes::time;
1741# warn $t2-$t1;
1742# }
1743
1550 video_init; 1744 video_init;
1551 audio_init; 1745 audio_init;
1552} 1746}
1553 1747
1554Event::loop; 1748Event::loop;
1608 1802
1609Typing B<climb> will display a list of commands with I<climb> in their 1803Typing B<climb> will display a list of commands with I<climb> in their
1610name, such as I<ready_skill climbing> and I<use_skill climbing>. 1804name, such as I<ready_skill climbing> and I<use_skill climbing>.
1611 1805
1612You can abbreviate commands by typing only the first character of every 1806You can abbreviate commands by typing only the first character of every
1613word. For example, typing I<iwor> will likely select I<invoke word of 1807word (or even characters within the word - the client will try to make
1614recall>, while I<ccfo> will select I<cast create food>. Likewise, I<rscli> 1808a good guess, as long as the characters are in order). For example,
1615will likely select I<ready_skill climbing> and I<usl> will give you 1809typing I<iwor> will likely select I<invoke word of recall>, while I<ccfo>
1616I<use_skill levitation>. 1810will select I<cast create food>. Likewise, I<rscli> will likely select
1811I<ready_skill climbing> and I<usl> will give you I<use_skill levitation>.
1812
1813You can enter space and other text as arguemnt to the command. For
1814example, C<cfoo waybread> will expand to C<cast create food waybread>.
1617 1815
1618=head2 The map overview 1816=head2 The map overview
1619 1817
1620#TODO# 1818#TODO#
1621 1819

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines