1 | #!/opt/bin/perl |
1 | #!/opt/bin/perl |
|
|
2 | |
|
|
3 | my $startup_done = sub { }; |
|
|
4 | |
|
|
5 | # do splash-screen thingy on win32 |
|
|
6 | BEGIN { |
|
|
7 | if (%PAR::LibCache && $^O eq "MSWin32") { |
|
|
8 | while (my ($filename, $zip) = each %PAR::LibCache) { |
|
|
9 | $zip->extractMember ("SPLASH.bmp", "$ENV{PAR_TEMP}/SPLASH.bmp"); |
|
|
10 | } |
|
|
11 | |
|
|
12 | require Win32::GUI::SplashScreen; |
|
|
13 | |
|
|
14 | Win32::GUI::SplashScreen::Show ( |
|
|
15 | -file => "$ENV{PAR_TEMP}/SPLASH.bmp", |
|
|
16 | ); |
|
|
17 | |
|
|
18 | $startup_done = sub { |
|
|
19 | Win32::GUI::SplashScreen::Done (1); |
|
|
20 | }; |
|
|
21 | } |
|
|
22 | } |
2 | |
23 | |
3 | use strict; |
24 | use strict; |
4 | use utf8; |
25 | use utf8; |
5 | |
26 | |
6 | # do things only needed for single-binary version (par) |
27 | # do things only needed for single-binary version (par) |
… | |
… | |
8 | if (%PAR::LibCache) { |
29 | if (%PAR::LibCache) { |
9 | @INC = grep ref, @INC; # weed out all paths except pars loader refs |
30 | @INC = grep ref, @INC; # weed out all paths except pars loader refs |
10 | |
31 | |
11 | while (my ($filename, $zip) = each %PAR::LibCache) { |
32 | while (my ($filename, $zip) = each %PAR::LibCache) { |
12 | for ($zip->memberNames) { |
33 | for ($zip->memberNames) { |
13 | next unless /^\/root\/(.*)/; |
34 | next unless /^root\/(.*)/; |
14 | $zip->extractMember ($_, "$ENV{PAR_TEMP}/$1") |
35 | $zip->extractMember ($_, "$ENV{PAR_TEMP}/$1") |
15 | unless -e "$ENV{PAR_TEMP}/$1"; |
36 | unless -e "$ENV{PAR_TEMP}/$1"; |
16 | } |
37 | } |
17 | } |
38 | } |
18 | |
39 | |
… | |
… | |
47 | |
68 | |
48 | $Event::Eval = 0; |
69 | $Event::Eval = 0; |
49 | $Event::DIED = sub { |
70 | $Event::DIED = sub { |
50 | # TODO: display dialog box or so |
71 | # TODO: display dialog box or so |
51 | Carp::cluck $_[1];#d#TODO: remove when stable |
72 | Carp::cluck $_[1];#d#TODO: remove when stable |
52 | CFPlus::error $_[1]; |
73 | return;#d# |
|
|
74 | CFPlus::fatal ($_[1]); |
53 | }; |
75 | }; |
54 | |
|
|
55 | $SIG{__DIE__} = sub { |
|
|
56 | return if CFPlus::in_destruct; |
|
|
57 | Carp::cluck $_[0]; |
|
|
58 | CFPlus::error $_[0]; |
|
|
59 | return;#d# |
|
|
60 | #return unless defined $^S && !$^S; |
|
|
61 | $Event::DIED->(undef, $_[0]); |
|
|
62 | }; |
|
|
63 | |
|
|
64 | our $VERSION = '0.1'; |
|
|
65 | |
76 | |
66 | my $MAX_FPS = 60; |
77 | my $MAX_FPS = 60; |
67 | my $MIN_FPS = 5; # unused as of yet |
78 | my $MIN_FPS = 5; # unused as of yet |
68 | |
79 | |
69 | our $META_SERVER = "crossfire.real-time.com:13326"; |
80 | our $META_SERVER = "http://metaserver.schmorp.de/current.json"; |
70 | |
81 | |
71 | our $LAST_REFRESH; |
82 | our $LAST_REFRESH; |
72 | our $NOW; |
83 | our $NOW; |
73 | |
84 | |
74 | our $CFG; |
85 | our $CFG; |
75 | our $CONN; |
86 | our $CONN; |
|
|
87 | our $PROFILE; # current profile |
76 | our $FAST; # fast, low-quality mode, possibly useful for software-rendering |
88 | our $FAST; # fast, low-quality mode, possibly useful for software-rendering |
77 | |
89 | |
78 | our $WANT_REFRESH; |
90 | our $WANT_REFRESH; |
79 | our $CAN_REFRESH; |
91 | our $CAN_REFRESH; |
80 | |
92 | |
… | |
… | |
146 | |
158 | |
147 | sub debug { |
159 | sub debug { |
148 | $DEBUG_STATUS->set_text ($_[0]); |
160 | $DEBUG_STATUS->set_text ($_[0]); |
149 | } |
161 | } |
150 | |
162 | |
|
|
163 | sub message { |
|
|
164 | my ($para) = @_; |
|
|
165 | |
|
|
166 | my $time = sprintf "%02d:%02d:%02d", (localtime time)[2,1,0]; |
|
|
167 | |
|
|
168 | $para->{markup} = "<span foreground='#ffffff'>$time</span> $para->{markup}"; |
|
|
169 | |
|
|
170 | $LOGVIEW->add_paragraph ($para); |
|
|
171 | $LOGVIEW->scroll_to_bottom; |
|
|
172 | } |
|
|
173 | |
151 | sub destroy_query_dialog { |
174 | sub destroy_query_dialog { |
152 | (delete $_[0]{query_dialog})->destroy |
175 | (delete $_[0]{query_dialog})->destroy |
153 | if $_[0]{query_dialog}; |
176 | if $_[0]{query_dialog}; |
154 | } |
177 | } |
155 | |
178 | |
156 | # server query dialog |
179 | # server query dialog |
157 | sub server_query { |
180 | sub server_query { |
158 | my ($conn, $flags, $prompt) = @_; |
181 | my ($conn, $flags, $prompt) = @_; |
159 | |
182 | |
160 | $conn->{query_dialog} = my $dialog = new CFPlus::UI::FancyFrame |
183 | $conn->{query_dialog} = my $dialog = new CFPlus::UI::Toplevel |
161 | x => "center", |
184 | x => "center", |
162 | y => "center", |
185 | y => "center", |
163 | title => "Server Query", |
186 | title => "Server Query", |
164 | child => my $vbox = new CFPlus::UI::VBox, |
187 | child => my $vbox = new CFPlus::UI::VBox, |
165 | ; |
188 | ; |
… | |
… | |
190 | ); |
213 | ); |
191 | |
214 | |
192 | $dialog->grab_focus; |
215 | $dialog->grab_focus; |
193 | |
216 | |
194 | } elsif ($flags & CS_QUERY_SINGLECHAR) { |
217 | } elsif ($flags & CS_QUERY_SINGLECHAR) { |
195 | $dialog->{tooltip} = "Press a key (click on the entry to make sure it has keyboard focus)"; |
218 | $dialog->{tooltip} = "#charcreation_focus"; |
196 | |
219 | |
197 | if ($prompt =~ /Now choose a character|Press any key for the next race/i) { |
220 | if ($prompt =~ /Now choose a character|Press any key for the next race/i) { |
198 | $MESSAGE_WINDOW->show; |
221 | $MESSAGE_WINDOW->show; |
199 | |
222 | |
200 | unshift @dialog, new CFPlus::UI::Label |
223 | unshift @dialog, new CFPlus::UI::Label |
… | |
… | |
222 | ); |
245 | ); |
223 | |
246 | |
224 | unshift @dialog, new CFPlus::UI::Label |
247 | unshift @dialog, new CFPlus::UI::Label |
225 | max_w => $::WIDTH * 0.4, |
248 | max_w => $::WIDTH * 0.4, |
226 | ellipsise => 0, |
249 | ellipsise => 0, |
227 | markup => |
250 | markup => (CFPlus::Pod::section_label ui => "chargen_race"), |
228 | "<big><b>Character Creation: Race</b></big>\n\n" |
|
|
229 | . "Look at the <b>Messages</b> window to see a description of this race " |
|
|
230 | . "and the center of the screen to see how this race looks like " |
|
|
231 | . "(<small>below this dialog window: you may need to move the dialog away and " |
|
|
232 | . "click into the display area to make it visible</small>).\n\n" |
|
|
233 | . "You can look at another race, or accept this race (you will cycle back to " |
|
|
234 | . "this race eventually, so you can take your time making this important choice." |
|
|
235 | ; |
251 | ; |
236 | |
252 | |
237 | } elsif ($prompt =~ /roll new stats/) { |
253 | } elsif ($prompt =~ /roll new stats/) { |
238 | if (my $stat = delete $conn->{stat_change_with}) { |
254 | if (my $stat = delete $conn->{stat_change_with}) { |
239 | $conn->send ("reply $stat"); |
255 | $conn->send ("reply $stat"); |
… | |
… | |
320 | } |
336 | } |
321 | |
337 | |
322 | unshift @dialog, new CFPlus::UI::Label |
338 | unshift @dialog, new CFPlus::UI::Label |
323 | max_w => $::WIDTH * 0.4, |
339 | max_w => $::WIDTH * 0.4, |
324 | ellipsise => 0, |
340 | ellipsise => 0, |
325 | markup => |
341 | markup => (CFPlus::Pod::section_label ui => "chargen_stats"), |
326 | "<big><b>Character Creation: Stats</b></big>\n\n" |
|
|
327 | . "<b>Stats</b> are a very important aspect of your character. You can use the tooltips to learn what each Stat governs.\n\n" |
|
|
328 | . "The stats generated by the server are always sorted from Str (highest) to Cha (lowest). " |
|
|
329 | . "They will be modified later by both the race and the class you choose.\n\n" |
|
|
330 | . "You can create another set of stats, swap two stat values with each other or accept the stats as shown below and continue.\n" |
|
|
331 | ; |
342 | ; |
332 | } |
343 | } |
333 | |
344 | |
334 | push @dialog, my $entry = new CFPlus::UI::Entry |
345 | push @dialog, my $entry = new CFPlus::UI::Entry |
335 | on_changed => sub { |
346 | on_changed => sub { |
… | |
… | |
364 | status "logging in..."; |
375 | status "logging in..."; |
365 | |
376 | |
366 | $LOGIN_BUTTON->set_text ("Logout"); |
377 | $LOGIN_BUTTON->set_text ("Logout"); |
367 | $SETUP_DIALOG->hide; |
378 | $SETUP_DIALOG->hide; |
368 | |
379 | |
|
|
380 | $PROFILE = $CFG->{profile}{default}; |
|
|
381 | |
369 | my $mapsize = List::Util::min 32, List::Util::max 11, int $WIDTH * $CFG->{mapsize} * 0.01 / 32; |
382 | my $mapsize = List::Util::min 32, List::Util::max 11, int $WIDTH * $CFG->{mapsize} * 0.01 / 32; |
370 | |
383 | |
371 | my ($host, $port) = split /:/, $CFG->{profile}{default}{host}; |
384 | my ($host, $port) = split /:/, $PROFILE->{host}; |
372 | |
385 | |
373 | $MAP = new CFPlus::Map $mapsize, $mapsize; |
386 | $MAP = new CFPlus::Map; |
374 | |
387 | |
375 | $CONN = eval { |
388 | $CONN = eval { |
376 | new CFPlus::Protocol |
389 | new CFPlus::Protocol |
377 | host => $host, |
390 | host => $host, |
378 | port => $port || 13327, |
391 | port => $port || 13327, |
379 | user => $CFG->{profile}{default}{user}, |
392 | user => $PROFILE->{user}, |
380 | pass => $CFG->{profile}{default}{password}, |
393 | pass => $PROFILE->{password}, |
381 | mapw => $mapsize, |
394 | mapw => $mapsize, |
382 | maph => $mapsize, |
395 | maph => $mapsize, |
|
|
396 | |
|
|
397 | client => "cfplus $CFPlus::VERSION $] $^O", |
383 | |
398 | |
384 | map_widget => $MAPWIDGET, |
399 | map_widget => $MAPWIDGET, |
385 | logview => $LOGVIEW, |
400 | logview => $LOGVIEW, |
386 | statusbox => $STATUSBOX, |
401 | statusbox => $STATUSBOX, |
387 | map => $MAP, |
402 | map => $MAP, |
… | |
… | |
622 | (new CFPlus::UI::Empty expand => 1), |
637 | (new CFPlus::UI::Empty expand => 1), |
623 | (my $hb = new CFPlus::UI::HBox), |
638 | (my $hb = new CFPlus::UI::HBox), |
624 | ], |
639 | ], |
625 | ); |
640 | ); |
626 | |
641 | |
627 | $hb->add (my $hg = new CFPlus::UI::Gauge type => 'hp', |
642 | $hb->add (my $hg = new CFPlus::UI::Gauge type => 'hp', tooltip => "#stat_health"); |
628 | 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."); |
|
|
629 | $hb->add (my $mg = new CFPlus::UI::Gauge type => 'mana', |
643 | $hb->add (my $mg = new CFPlus::UI::Gauge type => 'mana', tooltip => "#stat_mana"); |
630 | 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."); |
|
|
631 | $hb->add (my $gg = new CFPlus::UI::Gauge type => 'grace', |
644 | $hb->add (my $gg = new CFPlus::UI::Gauge type => 'grace', tooltip => "#stat_grace"); |
632 | 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."); |
|
|
633 | $hb->add (my $fg = new CFPlus::UI::Gauge type => 'food', |
645 | $hb->add (my $fg = new CFPlus::UI::Gauge type => 'food', tooltip => "#stat_food"); |
634 | 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."); |
|
|
635 | |
646 | |
636 | $vbox->add (my $exp = new CFPlus::UI::Label valign => 0, align => 1, can_hover => 1, can_events => 1, |
647 | $vbox->add (my $exp = new CFPlus::UI::Label valign => 0, align => 1, can_hover => 1, can_events => 1, tooltip => "#stat_exp"); |
637 | 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."); |
|
|
638 | $vbox->add (my $rng = new CFPlus::UI::Label valign => 0, align => 1, can_hover => 1, can_events => 1, |
648 | $vbox->add (my $rng = new CFPlus::UI::Label valign => 0, align => 1, can_hover => 1, can_events => 1, tooltip => "#stat_ranged"); |
639 | tooltip => "<b>Ranged attack</b> - how you attack when you press shift-cursor (spell, skill, weapon etc.)"); |
|
|
640 | |
649 | |
641 | $GAUGES = { |
650 | $GAUGES = { |
642 | exp => $exp, win => $win, range => $rng, |
651 | exp => $exp, win => $win, range => $rng, |
643 | food => $fg, mana => $mg, hp => $hg, grace => $gg |
652 | food => $fg, mana => $mg, hp => $hg, grace => $gg |
644 | }; |
653 | }; |
… | |
… | |
681 | expand => 1, |
690 | expand => 1, |
682 | scroll_y => 1 |
691 | scroll_y => 1 |
683 | ); |
692 | ); |
684 | $r->add (my $vb = new CFPlus::UI::VBox); |
693 | $r->add (my $vb = new CFPlus::UI::VBox); |
685 | |
694 | |
|
|
695 | $vb->add (new CFPlus::UI::FancyFrame |
|
|
696 | label => "Player", |
|
|
697 | child => (my $pi = new CFPlus::UI::VBox), |
|
|
698 | ); |
|
|
699 | |
686 | $vb->add ($STATWIDS->{title} = new CFPlus::UI::Label valign => 0, align => -1, text => "Title:", expand => 1, |
700 | $pi->add ($STATWIDS->{title} = new CFPlus::UI::Label valign => 0, align => -1, text => "Title:", expand => 1, |
687 | can_hover => 1, can_events => 1, |
701 | can_hover => 1, can_events => 1, |
688 | tooltip => "Your name and title. You can change your title by using the <b>title</b> command, if supported by the server."); |
702 | tooltip => "Your name and title. You can change your title by using the <b>title</b> command, if supported by the server."); |
689 | $vb->add ($STATWIDS->{map} = new CFPlus::UI::Label valign => 0, align => -1, text => "Map:", expand => 1, |
703 | $pi->add ($STATWIDS->{map} = new CFPlus::UI::Label valign => 0, align => -1, text => "Map:", expand => 1, |
690 | can_hover => 1, can_events => 1, |
704 | can_hover => 1, can_events => 1, |
691 | tooltip => "The map you are currently on (if supported by the server)."); |
705 | tooltip => "The map you are currently on (if supported by the server)."); |
692 | |
706 | |
693 | $vb->add (my $hb0 = new CFPlus::UI::HBox); |
707 | $pi->add (my $hb0 = new CFPlus::UI::HBox); |
694 | $hb0->add ($STATWIDS->{weight} = new CFPlus::UI::Label valign => 0, align => -1, text => "Weight:", expand => 1, |
708 | $hb0->add ($STATWIDS->{weight} = new CFPlus::UI::Label valign => 0, align => -1, text => "Weight:", expand => 1, |
695 | can_hover => 1, can_events => 1, |
709 | can_hover => 1, can_events => 1, |
696 | tooltip => "The weight of the player including all inventory items."); |
710 | tooltip => "The weight of the player including all inventory items."); |
697 | $hb0->add ($STATWIDS->{m_weight} = new CFPlus::UI::Label valign => 0, align => -1, text => "Max weight:", expand => 1, |
711 | $hb0->add ($STATWIDS->{m_weight} = new CFPlus::UI::Label valign => 0, align => -1, text => "Max weight:", expand => 1, |
698 | can_hover => 1, can_events => 1, |
712 | can_hover => 1, can_events => 1, |
699 | tooltip => "The weight limit: you cannot carry more than this."); |
713 | tooltip => "The weight limit: you cannot carry more than this."); |
700 | |
714 | |
|
|
715 | $vb->add (new CFPlus::UI::FancyFrame |
|
|
716 | label => "Primary/Secondary Statistics", |
701 | $vb->add (my $hb = new CFPlus::UI::HBox expand => 1); |
717 | child => (my $hb = new CFPlus::UI::HBox expand => 1), |
|
|
718 | ); |
702 | $hb->add (my $tbl = new CFPlus::UI::Table expand => 1); |
719 | $hb->add (my $tbl = new CFPlus::UI::Table expand => 1); |
703 | |
720 | |
704 | my $color2 = [1, 1, 0]; |
721 | my $color2 = [1, 1, 0]; |
705 | |
722 | |
706 | for ( |
723 | for ( |
… | |
… | |
727 | $tbl->add ($col + 1, $row, $STATWIDS->{"$id\_lbl"} = new CFPlus::UI::Label |
744 | $tbl->add ($col + 1, $row, $STATWIDS->{"$id\_lbl"} = new CFPlus::UI::Label |
728 | font => $FONT_FIXED, can_hover => 1, can_events => 1, fg => $color2, valign => 0, |
745 | font => $FONT_FIXED, can_hover => 1, can_events => 1, fg => $color2, valign => 0, |
729 | align => -1, text => $label, tooltip => "#stat_$label"); |
746 | align => -1, text => $label, tooltip => "#stat_$label"); |
730 | } |
747 | } |
731 | |
748 | |
|
|
749 | $vb->add (new CFPlus::UI::FancyFrame |
|
|
750 | label => "Resistancies", |
732 | $vb->add (my $tbl2 = new CFPlus::UI::Table expand => 1); |
751 | child => (my $tbl2 = new CFPlus::UI::Table expand => 1), |
|
|
752 | ); |
733 | |
753 | |
734 | my $row = 0; |
754 | my $row = 0; |
735 | my $col = 0; |
755 | my $col = 0; |
736 | |
756 | |
737 | my %resist_names = ( |
757 | my %resist_names = ( |
… | |
… | |
837 | |
857 | |
838 | my $table = $METASERVER->{table}; |
858 | my $table = $METASERVER->{table}; |
839 | $table->clear; |
859 | $table->clear; |
840 | $table->add (0, 0, my $label = new CFPlus::UI::Label max_w => $WIDTH * 0.8, text => "fetching server list..."); |
860 | $table->add (0, 0, my $label = new CFPlus::UI::Label max_w => $WIDTH * 0.8, text => "fetching server list..."); |
841 | |
861 | |
842 | my $buf; |
862 | my $ok = 0; |
843 | |
863 | |
844 | my $fh = new IO::Socket::INET PeerHost => $META_SERVER, Blocking => 0; |
864 | CFPlus::background { |
|
|
865 | my $ua = CFPlus::lwp_useragent; |
845 | |
866 | |
846 | unless ($fh) { |
867 | CFPlus::background_msg CFPlus::from_json +(CFPlus::lwp_check $ua->get ($META_SERVER))->decoded_content; |
847 | $label->set_text ("unable to contact metaserver: $!"); |
868 | } sub { |
848 | return; |
869 | my ($msg) = @_; |
849 | } |
870 | if ($msg) { |
850 | |
|
|
851 | Event->io (fd => $fh, poll => 'r', cb => sub { |
|
|
852 | my $res = sysread $fh, $buf, 8192, length $buf; |
|
|
853 | |
|
|
854 | if (!defined $res) { |
|
|
855 | $_[0]->w->cancel; |
|
|
856 | $label->set_text ("error while retrieving server list: $!"); |
|
|
857 | } elsif ($res == 0) { |
|
|
858 | $_[0]->w->cancel; |
|
|
859 | status "server list retrieved"; |
|
|
860 | |
|
|
861 | utf8::decode $buf if utf8::valid $buf; |
|
|
862 | |
|
|
863 | $table->clear; |
871 | $table->clear; |
864 | |
872 | |
865 | my @tip = ( |
873 | my @tip = ( |
866 | "The current number of users logged in on the server.", |
874 | "The current number of users logged in on the server.", |
867 | "The hostname of the server.", |
875 | "The hostname of the server.", |
… | |
… | |
877 | for 0 .. $#col; |
885 | for 0 .. $#col; |
878 | |
886 | |
879 | my @align = qw(1 0 1 1 -1); |
887 | my @align = qw(1 0 1 1 -1); |
880 | |
888 | |
881 | my $y = 0; |
889 | my $y = 0; |
882 | for my $m (sort { $b->[3] <=> $a->[3] } map [split /\|/], split /\015?\012/, $buf) { |
890 | for my $m ( |
|
|
891 | sort { |
|
|
892 | $b->{version} <=> $a->{version} |
|
|
893 | or $b->{users} <=> $a->{users} |
|
|
894 | } |
|
|
895 | @{ $msg->{servers} } |
|
|
896 | ) { |
883 | my ($ip, $last, $host, $users, $version, $desc, $ibytes, $obytes, $uptime) = @$m; |
897 | my ($ip, $last, $host, $users, $version, $desc, $ibytes, $obytes, $uptime) = |
|
|
898 | @$m{qw(ip age hostname users version description ibytes obytes uptime)}; |
884 | |
899 | |
885 | for ($desc) { |
900 | for ($desc) { |
886 | s/<br>/\n/gi; |
901 | s/<br>/\n/gi; |
887 | s/<li>/\n· /gi; |
902 | s/<li>/\n· /gi; |
888 | s/<.*?>//sgi; |
903 | s/<.*?>//sgi; |
889 | s/&/&/g; |
904 | s/&/&/g; |
890 | s/</</g; |
905 | s/</</g; |
891 | s/>/>/g; |
906 | s/>/>/g; |
892 | } |
907 | } |
893 | |
908 | |
894 | $uptime = sprintf "%dd %02d:%02d:%02d", |
909 | $uptime = sprintf "%dd %02d:%02d:%02d", |
895 | (int $m->[8] / 86400), |
910 | (int $uptime / 86400), |
896 | (int $m->[8] / 3600) % 24, |
911 | (int $uptime / 3600) % 24, |
897 | (int $m->[8] / 60) % 60, |
912 | (int $uptime / 60) % 60, |
898 | $m->[8] % 60; |
913 | $uptime % 60; |
899 | |
914 | |
900 | $m = [$users, $host, $uptime, $version, $desc]; |
915 | $m = [$users, $host, $uptime, $version, $desc]; |
901 | |
916 | |
902 | $y++; |
917 | $y++; |
903 | |
918 | |
… | |
… | |
913 | ), |
928 | ), |
914 | (new CFPlus::UI::Empty expand => 1), |
929 | (new CFPlus::UI::Empty expand => 1), |
915 | ]); |
930 | ]); |
916 | |
931 | |
917 | $table->add ($_, $y, new CFPlus::UI::Label |
932 | $table->add ($_, $y, new CFPlus::UI::Label |
|
|
933 | max_w => $::WIDTH * 0.4, |
918 | ellipsise => 0, |
934 | ellipsise => 0, |
919 | align => $align[$_], |
935 | align => $align[$_], |
920 | text => $m->[$_], |
936 | text => $m->[$_], |
921 | tooltip => $tip[$_], |
937 | tooltip => $tip[$_], |
|
|
938 | fg => ($m->[3] =~ /\+$/ ? [1, 1, 1] : [.7, .7, .7]), |
922 | can_hover => 1, |
939 | can_hover => 1, |
923 | can_events => 1, |
940 | can_events => 1, |
924 | fontsize => 0.8) |
941 | fontsize => 0.8) |
925 | for 0 .. $#$m; |
942 | for 0 .. $#$m; |
926 | } |
943 | } |
|
|
944 | } else { |
|
|
945 | $ok or $label->set_text ("error while contacting metaserver"); |
927 | } |
946 | } |
928 | }); |
947 | }; |
|
|
948 | |
929 | } |
949 | } |
930 | |
950 | |
931 | sub metaserver_dialog { |
951 | sub metaserver_dialog { |
932 | my $vbox = new CFPlus::UI::VBox; |
952 | my $vbox = new CFPlus::UI::VBox; |
933 | my $table = new CFPlus::UI::Table; |
953 | my $table = new CFPlus::UI::Table; |
934 | $vbox->add (new CFPlus::UI::ScrolledWindow expand => 1, child => $table); |
954 | $vbox->add (new CFPlus::UI::ScrolledWindow expand => 1, child => $table); |
935 | |
955 | |
936 | my $dialog = new CFPlus::UI::FancyFrame |
956 | my $dialog = new CFPlus::UI::Toplevel |
937 | title => "Server List", |
957 | title => "Server List", |
938 | name => 'metaserver_dialog', |
958 | name => 'metaserver_dialog', |
939 | x => 'center', |
959 | x => 'center', |
940 | y => 'center', |
960 | y => 'center', |
941 | z => 3, |
961 | z => 3, |
|
|
962 | force_w => $::WIDTH * 0.9, |
942 | force_h => $::HEIGHT * 0.4, |
963 | force_h => $::HEIGHT * 0.7, |
943 | child => $vbox, |
964 | child => $vbox, |
944 | has_close_button => 1, |
965 | has_close_button => 1, |
945 | table => $table, |
966 | table => $table, |
946 | on_visibility_change => sub { |
967 | on_visibility_change => sub { |
947 | update_metaserver ($_[0]) if $_[1]; |
968 | update_metaserver ($_[0]) if $_[1]; |
… | |
… | |
953 | } |
974 | } |
954 | |
975 | |
955 | sub server_setup { |
976 | sub server_setup { |
956 | my $vbox = new CFPlus::UI::VBox; |
977 | my $vbox = new CFPlus::UI::VBox; |
957 | |
978 | |
|
|
979 | $vbox->add (new CFPlus::UI::FancyFrame |
|
|
980 | label => "Connection Settings", |
958 | $vbox->add (my $table = new CFPlus::UI::Table expand => 1, col_expand => [0, 1]); |
981 | child => (my $table = new CFPlus::UI::Table expand => 1, col_expand => [0, 1]), |
|
|
982 | ); |
959 | $table->add (0, 2, new CFPlus::UI::Label valign => 0, align => 1, text => "Host:Port"); |
983 | $table->add (0, 2, new CFPlus::UI::Label valign => 0, align => 1, text => "Host:Port"); |
960 | |
984 | |
961 | { |
985 | { |
962 | $table->add (1, 2, my $vbox = new CFPlus::UI::VBox); |
986 | $table->add (1, 2, my $vbox = new CFPlus::UI::VBox); |
963 | |
987 | |
… | |
… | |
1047 | }, |
1071 | }, |
1048 | ); |
1072 | ); |
1049 | |
1073 | |
1050 | $table->add (0, 12, new CFPlus::UI::Label valign => 0, align => 1, text => "Chat Command"); |
1074 | $table->add (0, 12, new CFPlus::UI::Label valign => 0, align => 1, text => "Chat Command"); |
1051 | $table->add (1, 12, my $saycmd = new CFPlus::UI::Entry |
1075 | $table->add (1, 12, my $saycmd = new CFPlus::UI::Entry |
1052 | text => $CFG->{say_command}, |
1076 | text => $CFG->{say_command}, |
1053 | tooltip => "This is the command that will be used if you write a line in the message window entry or press <b>\"</b> in the map window. " |
1077 | tooltip => "This is the command that will be used if you write a line in the message window entry or press <b>\"</b> in the map window. " |
1054 | . "Usually you want to enter something like 'say' or 'shout' or 'gsay' here. " |
1078 | . "Usually you want to enter something like 'say' or 'shout' or 'gsay' here. " |
1055 | . "But you could also set it to <b>tell <i>playername</i></b> to only chat with that user.", |
1079 | . "But you could also set it to <b>tell <i>playername</i></b> to only chat with that user.", |
1056 | on_changed => sub { |
1080 | on_changed => sub { |
1057 | my ($self, $value) = @_; |
1081 | my ($self, $value) = @_; |
1058 | $CFG->{say_command} = $value; |
1082 | $CFG->{say_command} = $value; |
1059 | 0 |
1083 | 0 |
1060 | } |
1084 | } |
1061 | ); |
1085 | ); |
1062 | |
1086 | |
|
|
1087 | $table->add (0, 13, new CFPlus::UI::Label valign => 0, align => 1, text => "Tip of the day"); |
|
|
1088 | $table->add (1, 13, my $saycmd = new CFPlus::UI::CheckBox |
|
|
1089 | state => $CFG->{show_tips}, |
|
|
1090 | tooltip => "Show the <b>Tip of the day</b> window at startup?", |
|
|
1091 | on_changed => sub { |
|
|
1092 | my ($self, $value) = @_; |
|
|
1093 | $CFG->{show_tips} = $value; |
|
|
1094 | 0 |
|
|
1095 | } |
|
|
1096 | ); |
|
|
1097 | |
1063 | $vbox->add (new CFPlus::UI::Label |
1098 | $vbox->add (new CFPlus::UI::FancyFrame |
1064 | text => "Server Info", |
1099 | label => "Server Info", |
1065 | fontsize => 1.2, |
|
|
1066 | padding_y => 8, |
|
|
1067 | fg => [1, 1, 0, 1], |
|
|
1068 | ); |
|
|
1069 | |
|
|
1070 | $vbox->add ($SERVER_INFO = new CFPlus::UI::Label ellipsise => 0); |
1100 | child => ($SERVER_INFO = new CFPlus::UI::Label ellipsise => 0), |
|
|
1101 | ); |
1071 | |
1102 | |
1072 | $vbox |
1103 | $vbox |
1073 | } |
1104 | } |
1074 | |
1105 | |
1075 | sub message_window { |
1106 | sub message_window { |
1076 | my $window = new CFPlus::UI::FancyFrame |
1107 | my $window = new CFPlus::UI::Toplevel |
1077 | name => "message_window", |
1108 | name => "message_window", |
1078 | title => "Messages", |
1109 | title => "Messages", |
1079 | border_bg => [1, 1, 1, 1], |
1110 | border_bg => [1, 1, 1, 1], |
1080 | x => "max", |
1111 | x => "max", |
1081 | y => 0, |
1112 | y => 0, |
… | |
… | |
1131 | window => $window, |
1162 | window => $window, |
1132 | input => $input, |
1163 | input => $input, |
1133 | }; |
1164 | }; |
1134 | |
1165 | |
1135 | $window |
1166 | $window |
1136 | } |
|
|
1137 | |
|
|
1138 | sub open_string_query { |
|
|
1139 | my $cb = $_[1]; |
|
|
1140 | my $dialog = new CFPlus::UI::FancyFrame |
|
|
1141 | x => "center", |
|
|
1142 | y => "center", |
|
|
1143 | z => 50, |
|
|
1144 | force_w => $WIDTH * 4/5, |
|
|
1145 | title => $_[0]; |
|
|
1146 | |
|
|
1147 | $dialog->add ( |
|
|
1148 | my $e = new CFPlus::UI::Entry |
|
|
1149 | on_activate => sub { $cb->(@_); $dialog->hide; 0 }, |
|
|
1150 | on_key_down => sub { $_[1]->{sym} == 27 and $dialog->hide; 0 }, |
|
|
1151 | ); |
|
|
1152 | |
|
|
1153 | $e->grab_focus; |
|
|
1154 | $dialog->show; |
|
|
1155 | } |
|
|
1156 | |
|
|
1157 | sub open_quit_dialog { |
|
|
1158 | unless ($QUIT_DIALOG) { |
|
|
1159 | $QUIT_DIALOG = new CFPlus::UI::FancyFrame |
|
|
1160 | x => "center", |
|
|
1161 | y => "center", |
|
|
1162 | z => 50, |
|
|
1163 | title => "Really Quit?", |
|
|
1164 | on_key_down => sub { |
|
|
1165 | my ($dialog, $ev) = @_; |
|
|
1166 | $ev->{sym} == 27 and $dialog->hide; |
|
|
1167 | } |
|
|
1168 | ; |
|
|
1169 | |
|
|
1170 | $QUIT_DIALOG->add (my $vb = new CFPlus::UI::VBox expand => 1); |
|
|
1171 | |
|
|
1172 | $vb->add (new CFPlus::UI::Label |
|
|
1173 | text => "You should find a savebed and apply it first!", |
|
|
1174 | max_w => $WIDTH * 0.25, |
|
|
1175 | ellipsize => 0, |
|
|
1176 | ); |
|
|
1177 | $vb->add (my $hb = new CFPlus::UI::HBox expand => 1); |
|
|
1178 | $hb->add (new CFPlus::UI::Button |
|
|
1179 | text => "Ok", |
|
|
1180 | expand => 1, |
|
|
1181 | on_activate => sub { $QUIT_DIALOG->hide; 0 }, |
|
|
1182 | ); |
|
|
1183 | $hb->add (new CFPlus::UI::Button |
|
|
1184 | text => "Quit anyway", |
|
|
1185 | expand => 1, |
|
|
1186 | on_activate => sub { exit }, |
|
|
1187 | ); |
|
|
1188 | } |
|
|
1189 | |
|
|
1190 | $QUIT_DIALOG->show; |
|
|
1191 | $QUIT_DIALOG->grab_focus; |
|
|
1192 | } |
1167 | } |
1193 | |
1168 | |
1194 | sub autopickup_setup { |
1169 | sub autopickup_setup { |
1195 | my $table = new CFPlus::UI::Table; |
1170 | my $table = new CFPlus::UI::Table; |
1196 | |
1171 | |
… | |
… | |
1327 | #TODO# update to weigh/maxweight |
1302 | #TODO# update to weigh/maxweight |
1328 | $hb1->add ($STATWIDS->{i_weight} = new CFPlus::UI::Label align => -1); |
1303 | $hb1->add ($STATWIDS->{i_weight} = new CFPlus::UI::Label align => -1); |
1329 | |
1304 | |
1330 | $vb1->add (my $sw1 = new CFPlus::UI::ScrolledWindow expand => 1, scroll_y => 1); |
1305 | $vb1->add (my $sw1 = new CFPlus::UI::ScrolledWindow expand => 1, scroll_y => 1); |
1331 | $sw1->add ($INV = new CFPlus::UI::Inventory); |
1306 | $sw1->add ($INV = new CFPlus::UI::Inventory); |
|
|
1307 | $INV->set_sort_order ($SORT_ORDER{$::CFG->{inv_sort}}); |
1332 | |
1308 | |
1333 | $hb->add (my $vb2 = new CFPlus::UI::VBox); |
1309 | $hb->add (my $vb2 = new CFPlus::UI::VBox); |
1334 | |
1310 | |
1335 | $vb2->add ($INV_RIGHT_HB = new CFPlus::UI::HBox); |
1311 | $vb2->add ($INV_RIGHT_HB = new CFPlus::UI::HBox); |
1336 | |
1312 | |
… | |
… | |
1353 | $PL_WINDOW->show; |
1329 | $PL_WINDOW->show; |
1354 | } |
1330 | } |
1355 | } |
1331 | } |
1356 | |
1332 | |
1357 | sub player_window { |
1333 | sub player_window { |
1358 | my $plwin = $PL_WINDOW = new CFPlus::UI::FancyFrame |
1334 | my $plwin = $PL_WINDOW = new CFPlus::UI::Toplevel |
1359 | x => "center", |
1335 | x => "center", |
1360 | y => "center", |
1336 | y => "center", |
1361 | force_w => $WIDTH * 9/10, |
1337 | force_w => $WIDTH * 9/10, |
1362 | force_h => $HEIGHT * 9/10, |
1338 | force_h => $HEIGHT * 9/10, |
1363 | title => "Player", |
1339 | title => "Player", |
… | |
… | |
1405 | |
1381 | |
1406 | my $refresh; |
1382 | my $refresh; |
1407 | $refresh = $BIND_UPD_CB = sub { |
1383 | $refresh = $BIND_UPD_CB = sub { |
1408 | $binding_list->clear (); |
1384 | $binding_list->clear (); |
1409 | |
1385 | |
|
|
1386 | return unless $PROFILE; |
|
|
1387 | |
1410 | for my $mod (keys %{$::CFG->{profile}{default}{bindings}}) { |
1388 | for my $mod (keys %{$PROFILE->{bindings}}) { |
1411 | for my $sym (keys %{$::CFG->{profile}{default}{bindings}{$mod}}) { |
1389 | for my $sym (keys %{$PROFILE->{bindings}{$mod}}) { |
1412 | my $cmds = $::CFG->{profile}{default}{bindings}{$mod}{$sym}; |
1390 | my $cmds = $PROFILE->{bindings}{$mod}{$sym}; |
1413 | next unless ref $cmds eq 'ARRAY' and @$cmds > 0; |
1391 | next unless ref $cmds eq 'ARRAY' and @$cmds > 0; |
1414 | |
1392 | |
1415 | my $lbl = join "; ", @$cmds; |
1393 | my $lbl = join "; ", @$cmds; |
1416 | my $nam = CFPlus::BindingEditor::keycombo_to_name ($mod, $sym); |
1394 | my $nam = CFPlus::BindingEditor::keycombo_to_name ($mod, $sym); |
1417 | $binding_list->add (my $hb = new CFPlus::UI::HBox); |
1395 | $binding_list->add (my $hb = new CFPlus::UI::HBox); |
1418 | $hb->add (new CFPlus::UI::Button |
1396 | $hb->add (new CFPlus::UI::Button |
1419 | text => "delete", |
1397 | text => "delete", |
1420 | tooltip => "Deletes the binding", |
1398 | tooltip => "Deletes the binding", |
1421 | on_activate => sub { |
1399 | on_activate => sub { |
1422 | $binding_list->remove ($hb); |
1400 | $binding_list->remove ($hb); |
1423 | delete $::CFG->{profile}{default}{bindings}{$mod}{$sym}; |
1401 | delete $PROFILE->{bindings}{$mod}{$sym}; |
1424 | 0 |
1402 | 0 |
1425 | }); |
1403 | }); |
1426 | |
1404 | |
1427 | $hb->add (new CFPlus::UI::Button |
1405 | $hb->add (new CFPlus::UI::Button |
1428 | text => "edit", |
1406 | text => "edit", |
1429 | tooltip => "Edits the binding", |
1407 | tooltip => "Edits the binding", |
1430 | on_activate => sub { |
1408 | on_activate => sub { |
1431 | $::BIND_EDITOR->set_binding ( |
1409 | $::BIND_EDITOR->set_binding ( |
1432 | $mod, $sym, $::CFG->{profile}{default}{bindings}{$mod}{$sym}, |
1410 | $mod, $sym, $PROFILE->{bindings}{$mod}{$sym}, |
1433 | sub { |
1411 | sub { |
1434 | my ($nmod, $nsym, $ncmds) = @_; |
1412 | my ($nmod, $nsym, $ncmds) = @_; |
1435 | $::BIND_EDITOR->cfg_unbind ($mod, $sym); |
1413 | $::BIND_EDITOR->cfg_unbind ($mod, $sym); |
1436 | $::BIND_EDITOR->cfg_bind ($nmod, $nsym, $ncmds); |
1414 | $::BIND_EDITOR->cfg_bind ($nmod, $nsym, $ncmds); |
1437 | $refresh->(); |
1415 | $refresh->(); |
… | |
… | |
1452 | } |
1430 | } |
1453 | } |
1431 | } |
1454 | }; |
1432 | }; |
1455 | |
1433 | |
1456 | my $vb = new CFPlus::UI::VBox; |
1434 | my $vb = new CFPlus::UI::VBox; |
|
|
1435 | $vb->add (new CFPlus::UI::FancyFrame |
|
|
1436 | label => "Options", |
1457 | $vb->add (my $hb = new CFPlus::UI::HBox); |
1437 | child => (my $hb = new CFPlus::UI::HBox), |
|
|
1438 | ); |
1458 | $hb->add (new CFPlus::UI::Label text => "only shift-up stops fire"); |
1439 | $hb->add (new CFPlus::UI::Label text => "only shift-up stops fire"); |
1459 | $hb->add (new CFPlus::UI::CheckBox |
1440 | $hb->add (new CFPlus::UI::CheckBox |
1460 | expand => 1, |
1441 | expand => 1, |
1461 | state => $CFG->{shift_fire_stop}, |
1442 | state => $CFG->{shift_fire_stop}, |
1462 | tooltip => "If this checkbox is enabled you will stop fire only if you stop pressing shift", |
1443 | tooltip => "If this checkbox is enabled you will stop fire only if you stop pressing shift", |
… | |
… | |
1464 | my ($cbox, $value) = @_; |
1445 | my ($cbox, $value) = @_; |
1465 | $CFG->{shift_fire_stop} = $value; |
1446 | $CFG->{shift_fire_stop} = $value; |
1466 | 0 |
1447 | 0 |
1467 | }); |
1448 | }); |
1468 | |
1449 | |
1469 | $vb->add ($binding_list); |
1450 | $vb->add (new CFPlus::UI::FancyFrame |
|
|
1451 | label => "Bindings", |
|
|
1452 | child => $binding_list); |
1470 | $vb->add (my $hb = new CFPlus::UI::HBox); |
1453 | $vb->add (my $hb = new CFPlus::UI::HBox); |
1471 | |
1454 | |
1472 | $hb->add (new CFPlus::UI::Button |
1455 | $hb->add (new CFPlus::UI::Button |
1473 | text => "record new", |
1456 | text => "record new", |
1474 | expand => 1, |
1457 | expand => 1, |
… | |
… | |
1507 | |
1490 | |
1508 | $vb |
1491 | $vb |
1509 | } |
1492 | } |
1510 | |
1493 | |
1511 | sub help_window { |
1494 | sub help_window { |
1512 | my $win = new CFPlus::UI::FancyFrame |
1495 | my $win = new CFPlus::UI::Toplevel |
1513 | x => 'center', |
1496 | x => 'center', |
1514 | y => 'center', |
1497 | y => 'center', |
1515 | z => 2, |
1498 | z => 4, |
1516 | name => 'doc_browser', |
1499 | name => 'doc_browser', |
1517 | force_w => int $WIDTH * 7/8, |
1500 | force_w => int $WIDTH * 7/8, |
1518 | force_h => int $HEIGHT * 7/8, |
1501 | force_h => int $HEIGHT * 7/8, |
1519 | title => "Help Browser", |
1502 | title => "Help Browser", |
1520 | has_close_button => 1; |
1503 | has_close_button => 1; |
1521 | |
1504 | |
1522 | $win->add (my $vbox = new CFPlus::UI::VBox); |
1505 | $win->add (my $vbox = new CFPlus::UI::VBox); |
1523 | |
1506 | |
|
|
1507 | $vbox->add (new CFPlus::UI::FancyFrame |
|
|
1508 | label => "Navigation", |
1524 | $vbox->add (my $buttons = new CFPlus::UI::HBox); |
1509 | child => (my $buttons = new CFPlus::UI::HBox), |
|
|
1510 | ); |
1525 | $vbox->add (my $viewer = new CFPlus::UI::TextScroller |
1511 | $vbox->add (my $viewer = new CFPlus::UI::TextScroller |
1526 | expand => 1, fontsize => 0.8, padding_x => 4); |
1512 | expand => 1, fontsize => 0.8, padding_x => 4, padding_y => 4); |
1527 | |
1513 | |
1528 | $buttons->add (new CFPlus::UI::Label text => "Choose a document to display: "); |
1514 | my @history; |
1529 | $buttons->add (my $combo = new CFPlus::UI::Selector |
1515 | my @future; |
1530 | value => undef, |
1516 | my $curnode; |
1531 | options => [ |
1517 | |
1532 | [intro => "Introduction"], |
1518 | my $load_node; $load_node = sub { |
1533 | [manual => "Main Manual"], |
1519 | my ($node, $para) = @_; |
1534 | [skill_help => "Skill Reference"], |
1520 | |
1535 | [command_help => "Command Reference"], |
1521 | $buttons->clear; |
1536 | [dmcommand_help => "DM Commands"], |
1522 | |
1537 | [COPYING => "License Terms"], |
1523 | $buttons->add (new CFPlus::UI::Button |
|
|
1524 | text => "⇤", |
|
|
1525 | tooltip => "back to the starting page", |
|
|
1526 | on_activate => sub { |
|
|
1527 | unshift @future, [$curnode, $viewer->current_paragraph] if $curnode; |
|
|
1528 | unshift @future, @history; |
|
|
1529 | @history = (); |
|
|
1530 | $load_node->(@{shift @future}); |
|
|
1531 | }, |
|
|
1532 | ); |
|
|
1533 | |
|
|
1534 | if (@history) { |
|
|
1535 | $buttons->add (new CFPlus::UI::Button |
|
|
1536 | text => "⋘", |
|
|
1537 | tooltip => "back to <i>" . (CFPlus::asxml CFPlus::Pod::full_path $history[-1][0]) . "</i>", |
|
|
1538 | on_activate => sub { |
|
|
1539 | unshift @future, [$curnode, $viewer->current_paragraph] if $curnode; |
|
|
1540 | $load_node->(@{pop @history}); |
|
|
1541 | }, |
|
|
1542 | ); |
1538 | ], |
1543 | } |
1539 | on_changed => sub { |
|
|
1540 | my ($self, $pod) = @_; |
|
|
1541 | |
1544 | |
|
|
1545 | if (@future) { |
|
|
1546 | $buttons->add (new CFPlus::UI::Button |
|
|
1547 | text => "⋙", |
|
|
1548 | tooltip => "forward to <i>" . (CFPlus::asxml CFPlus::Pod::full_path $future[0][0]) . "</i>", |
|
|
1549 | on_activate => sub { |
|
|
1550 | push @history, [$curnode, $viewer->current_paragraph]; |
|
|
1551 | $load_node->(@{shift @future}); |
|
|
1552 | }, |
|
|
1553 | ); |
|
|
1554 | } |
|
|
1555 | |
|
|
1556 | $buttons->add (new CFPlus::UI::Label text => " "); |
|
|
1557 | |
|
|
1558 | my @path = CFPlus::Pod::full_path_of $node; |
|
|
1559 | pop @path; # drop current node |
|
|
1560 | |
|
|
1561 | for my $node (@path) { |
|
|
1562 | $buttons->add (new CFPlus::UI::Button |
|
|
1563 | text => $node->{kw}[0], |
|
|
1564 | tooltip => "go to <i>" . (CFPlus::asxml CFPlus::Pod::full_path $node) . "</i>", |
|
|
1565 | on_activate => sub { |
|
|
1566 | push @history, [$curnode, $viewer->current_paragraph] if $curnode; @future = (); |
|
|
1567 | $load_node->($node); |
|
|
1568 | }, |
|
|
1569 | ); |
|
|
1570 | $buttons->add (new CFPlus::UI::Label text => "/"); |
|
|
1571 | } |
|
|
1572 | |
|
|
1573 | $buttons->add (new CFPlus::UI::Label text => $node->{kw}[0], padding_x => 4, padding_y => 4); |
|
|
1574 | |
|
|
1575 | $curnode = $node; |
|
|
1576 | |
1542 | $viewer->clear; |
1577 | $viewer->clear; |
1543 | $viewer->add_paragraph (CFPlus::Pod::section pod => $pod); |
1578 | $viewer->add_paragraph (CFPlus::Pod::as_paragraphs CFPlus::Pod::section_of $curnode); |
1544 | $viewer->set_offset (0); |
1579 | $viewer->scroll_to ($para); |
|
|
1580 | }; |
1545 | |
1581 | |
|
|
1582 | $load_node->(CFPlus::Pod::find pod => "mainpage"); |
|
|
1583 | |
|
|
1584 | $CFPlus::Pod::goto_document = sub { |
|
|
1585 | my (@path) = @_; |
|
|
1586 | |
|
|
1587 | push @history, [$curnode, $viewer->current_paragraph] if $curnode; @future = (); |
|
|
1588 | |
|
|
1589 | $load_node->((CFPlus::Pod::find @path)[0]); |
|
|
1590 | $win->show; |
|
|
1591 | }; |
|
|
1592 | |
|
|
1593 | $win |
|
|
1594 | } |
|
|
1595 | |
|
|
1596 | sub open_string_query { |
|
|
1597 | my ($title, $cb, $txt, $tooltip) = @_; |
|
|
1598 | my $dialog = new CFPlus::UI::Toplevel |
|
|
1599 | x => "center", |
|
|
1600 | y => "center", |
|
|
1601 | z => 50, |
|
|
1602 | force_w => $WIDTH * 4/5, |
|
|
1603 | title => $title; |
|
|
1604 | |
|
|
1605 | $dialog->add ( |
|
|
1606 | my $e = new CFPlus::UI::Entry |
|
|
1607 | on_activate => sub { $cb->(@_); $dialog->hide; 0 }, |
|
|
1608 | on_key_down => sub { $_[1]->{sym} == 27 and $dialog->hide; 0 }, |
|
|
1609 | tooltip => $tooltip |
|
|
1610 | ); |
|
|
1611 | |
|
|
1612 | $e->grab_focus; |
|
|
1613 | $e->set_text ($txt) if $txt; |
|
|
1614 | $dialog->show; |
|
|
1615 | } |
|
|
1616 | |
|
|
1617 | sub open_quit_dialog { |
|
|
1618 | unless ($QUIT_DIALOG) { |
|
|
1619 | $QUIT_DIALOG = new CFPlus::UI::Toplevel |
|
|
1620 | x => "center", |
|
|
1621 | y => "center", |
|
|
1622 | z => 50, |
|
|
1623 | title => "Really Quit?", |
|
|
1624 | on_key_down => sub { |
|
|
1625 | my ($dialog, $ev) = @_; |
|
|
1626 | $ev->{sym} == 27 and $dialog->hide; |
1546 | 0 |
1627 | } |
|
|
1628 | ; |
|
|
1629 | |
|
|
1630 | $QUIT_DIALOG->add (my $vb = new CFPlus::UI::VBox expand => 1); |
|
|
1631 | |
|
|
1632 | $vb->add (new CFPlus::UI::Label |
|
|
1633 | text => "You should find a savebed and apply it first!", |
|
|
1634 | max_w => $WIDTH * 0.25, |
|
|
1635 | ellipsize => 0, |
|
|
1636 | ); |
|
|
1637 | $vb->add (my $hb = new CFPlus::UI::HBox expand => 1); |
|
|
1638 | $hb->add (new CFPlus::UI::Button |
|
|
1639 | text => "Ok", |
|
|
1640 | expand => 1, |
|
|
1641 | on_activate => sub { $QUIT_DIALOG->hide; 0 }, |
|
|
1642 | ); |
|
|
1643 | $hb->add (new CFPlus::UI::Button |
|
|
1644 | text => "Quit anyway", |
|
|
1645 | expand => 1, |
|
|
1646 | on_activate => sub { exit }, |
|
|
1647 | ); |
|
|
1648 | } |
|
|
1649 | |
|
|
1650 | $QUIT_DIALOG->show; |
|
|
1651 | $QUIT_DIALOG->grab_focus; |
|
|
1652 | } |
|
|
1653 | |
|
|
1654 | sub show_tip_of_the_day { |
|
|
1655 | # find all tips |
|
|
1656 | my @tod = CFPlus::Pod::find tip_of_the_day => "*"; |
|
|
1657 | |
|
|
1658 | my $todindex = $CFPlus::DB_STATE->get ("tip_of_the_day"); |
|
|
1659 | $todindex = 0 if $todindex >= @tod; |
|
|
1660 | $CFPlus::DB_STATE->put (tip_of_the_day => $todindex + 1); |
|
|
1661 | |
|
|
1662 | # create dialog |
|
|
1663 | my $dialog; |
|
|
1664 | |
|
|
1665 | my $close = sub { |
|
|
1666 | $dialog->destroy; |
|
|
1667 | }; |
|
|
1668 | |
|
|
1669 | $dialog = new CFPlus::UI::Toplevel |
|
|
1670 | x => "center", |
|
|
1671 | y => "center", |
|
|
1672 | z => 3, |
|
|
1673 | name => 'tip_of_the_day', |
|
|
1674 | force_w => int $WIDTH * 4/9, |
|
|
1675 | force_h => int $WIDTH * 2/9, |
|
|
1676 | title => "Tip of the day #" . (1 + $todindex), |
|
|
1677 | child => my $vbox = new CFPlus::UI::VBox, |
|
|
1678 | has_close_button => 1, |
|
|
1679 | on_delete => $close, |
|
|
1680 | ; |
|
|
1681 | |
|
|
1682 | $vbox->add (my $viewer = new CFPlus::UI::TextScroller |
|
|
1683 | expand => 1, fontsize => 0.8, padding_x => 4, padding_y => 4); |
|
|
1684 | $viewer->add_paragraph (CFPlus::Pod::as_paragraphs CFPlus::Pod::section_of $tod[$todindex]); |
|
|
1685 | |
|
|
1686 | $vbox->add (my $table = new CFPlus::UI::Table); |
|
|
1687 | |
|
|
1688 | $table->add (0, 0, new CFPlus::UI::Button |
|
|
1689 | text => "Close", |
|
|
1690 | tooltip => "Close the tip of the day window. To never see it again, disable the tip of the day in the <b>Server Setup</b>.", |
|
|
1691 | on_activate => $close, |
|
|
1692 | ); |
|
|
1693 | |
|
|
1694 | $table->add (2, 0, new CFPlus::UI::Button |
|
|
1695 | text => "Next", |
|
|
1696 | tooltip => "Show the next <b>Tip of the day</b>.", |
|
|
1697 | on_activate => sub { |
|
|
1698 | $close->(); |
|
|
1699 | &show_tip_of_the_day; |
1547 | }, |
1700 | }, |
1548 | on_visibility_change => sub { |
|
|
1549 | my ($self, $visible) = @_; |
|
|
1550 | return unless $visible; |
|
|
1551 | return if $self->{value}; |
|
|
1552 | $self->set_value ("intro"); |
|
|
1553 | 0 |
|
|
1554 | }, |
|
|
1555 | ); |
1701 | ); |
1556 | |
1702 | |
1557 | $win |
1703 | $dialog->show; |
1558 | } |
1704 | } |
1559 | |
1705 | |
1560 | sub sdl_init { |
1706 | sub sdl_init { |
1561 | CFPlus::SDL_Init |
1707 | CFPlus::SDL_Init |
1562 | and die "SDL::Init failed!\n"; |
1708 | and die "SDL::Init failed!\n"; |
… | |
… | |
1609 | force_x => 0, |
1755 | force_x => 0, |
1610 | force_y => "max", |
1756 | force_y => "max", |
1611 | child => $STATUSBOX, |
1757 | child => $STATUSBOX, |
1612 | )->show; |
1758 | )->show; |
1613 | |
1759 | |
1614 | CFPlus::UI::FancyFrame->new ( |
1760 | CFPlus::UI::Toplevel->new ( |
1615 | title => "Map", |
1761 | title => "Map", |
1616 | name => "mapmap", |
1762 | name => "mapmap", |
1617 | x => 0, |
1763 | x => 0, |
1618 | y => $FONTSIZE + 8, |
1764 | y => $FONTSIZE + 8, |
1619 | border_bg => [1, 1, 1, 192/255], |
1765 | border_bg => [1, 1, 1, 192/255], |
… | |
… | |
1647 | can_hover => 1, |
1793 | can_hover => 1, |
1648 | can_events => 1, |
1794 | can_events => 1, |
1649 | tooltip => "<b>Server Log</b>. This text viewer contains all the messages sent by the server.", |
1795 | tooltip => "<b>Server Log</b>. This text viewer contains all the messages sent by the server.", |
1650 | ; |
1796 | ; |
1651 | |
1797 | |
1652 | $SETUP_DIALOG = new CFPlus::UI::FancyFrame |
1798 | $SETUP_DIALOG = new CFPlus::UI::Toplevel |
1653 | title => "Setup", |
1799 | title => "Setup", |
1654 | name => "setup_dialog", |
1800 | name => "setup_dialog", |
1655 | x => 'center', |
1801 | x => 'center', |
1656 | y => 'center', |
1802 | y => 'center', |
1657 | z => 2, |
1803 | z => 2, |
… | |
… | |
1769 | CFPlus::MixMusic::volume $CFG->{bgm_volume} * 128; |
1915 | CFPlus::MixMusic::volume $CFG->{bgm_volume} * 128; |
1770 | |
1916 | |
1771 | audio_music_finished; |
1917 | audio_music_finished; |
1772 | |
1918 | |
1773 | while (<$fh>) { |
1919 | while (<$fh>) { |
|
|
1920 | last; |
1774 | next if /^\s*#/; |
1921 | next if /^\s*#/; |
1775 | next if /^\s*$/; |
1922 | next if /^\s*$/; |
1776 | |
1923 | |
1777 | my ($file, $volume, $event) = split /\s+/, $_, 3; |
1924 | my ($file, $volume, $event) = split /\s+/, $_, 3; |
1778 | |
1925 | |
1779 | push @SOUNDS, "$volume,$file"; |
1926 | push @SOUNDS, "$volume,$file"; |
1780 | |
1927 | |
1781 | $AUDIO_CHUNKS{"$volume,$file"} ||= do { |
1928 | # $AUDIO_CHUNKS{"$volume,$file"} ||= do { |
1782 | my $chunk = new_from_file CFPlus::MixChunk CFPlus::find_rcfile "sounds/$file"; |
1929 | # my $chunk = new_from_file CFPlus::MixChunk CFPlus::find_rcfile "sounds/$file"; |
1783 | $chunk->volume ($volume * 128 / 100); |
1930 | # $chunk->volume ($volume * 128 / 100); |
1784 | $chunk |
1931 | # $chunk |
1785 | }; |
1932 | # }; |
1786 | } |
1933 | } |
1787 | } else { |
1934 | } else { |
1788 | status "unable to open sound config: $!"; |
1935 | status "unable to open sound config: $!"; |
1789 | } |
1936 | } |
1790 | } |
1937 | } |
… | |
… | |
1911 | log_fontsize => 0.7, |
2058 | log_fontsize => 0.7, |
1912 | gauge_fontsize => 1, |
2059 | gauge_fontsize => 1, |
1913 | gauge_size => 0.35, |
2060 | gauge_size => 0.35, |
1914 | stat_fontsize => 0.7, |
2061 | stat_fontsize => 0.7, |
1915 | mapsize => 100, |
2062 | mapsize => 100, |
1916 | say_command => 'say', |
2063 | say_command => 'chat', |
1917 | audio_enable => 1, |
2064 | audio_enable => 1, |
1918 | bgm_enable => 1, |
2065 | bgm_enable => 1, |
1919 | bgm_volume => 0.25, |
2066 | bgm_volume => 0.25, |
1920 | face_prefetch => 0, |
2067 | face_prefetch => 0, |
1921 | output_sync => 1, |
2068 | output_sync => 1, |
1922 | output_count => 1, |
2069 | output_count => 1, |
1923 | pickup => 0, |
2070 | pickup => 0, |
1924 | inv_sort => "mtime", |
2071 | inv_sort => "mtime", |
1925 | default => "profile", # default profile |
2072 | default => "profile", # default profile |
|
|
2073 | show_tips => 1, |
1926 | ); |
2074 | ); |
1927 | |
2075 | |
1928 | while (my ($k, $v) = each %DEF_CFG) { |
2076 | while (my ($k, $v) = each %DEF_CFG) { |
1929 | $CFG->{$k} = $v unless exists $CFG->{$k}; |
2077 | $CFG->{$k} = $v unless exists $CFG->{$k}; |
1930 | } |
2078 | } |
… | |
… | |
1974 | # } |
2122 | # } |
1975 | # my $t2 = Time::HiRes::time; |
2123 | # my $t2 = Time::HiRes::time; |
1976 | # warn $t2-$t1; |
2124 | # warn $t2-$t1; |
1977 | # } |
2125 | # } |
1978 | |
2126 | |
|
|
2127 | $startup_done->(); |
|
|
2128 | |
1979 | video_init; |
2129 | video_init; |
1980 | audio_init; |
2130 | audio_init; |
1981 | } |
2131 | } |
|
|
2132 | |
|
|
2133 | show_tip_of_the_day if $CFG->{show_tips}; |
1982 | |
2134 | |
1983 | Event::loop; |
2135 | Event::loop; |
1984 | #CFPlus::SDL_Quit; |
2136 | #CFPlus::SDL_Quit; |
1985 | #CFPlus::_exit 0; |
2137 | #CFPlus::_exit 0; |
1986 | |
2138 | |