ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/DC.pm
Revision: 1.72
Committed: Sat May 27 20:46:54 2006 UTC (17 years, 11 months ago) by root
Branch: MAIN
Changes since 1.71: +3 -3 lines
Log Message:
renamed connect_xxx to on_xxx

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3 root 1.22 CFClient - undocumented utility garbage for our crossfire client
4 root 1.1
5     =head1 SYNOPSIS
6    
7 root 1.22 use CFClient;
8 root 1.1
9     =head1 DESCRIPTION
10    
11     =over 4
12    
13     =cut
14    
15 root 1.22 package CFClient;
16 root 1.1
17     BEGIN {
18     $VERSION = '0.1';
19    
20 root 1.2 use XSLoader;
21 root 1.22 XSLoader::load "CFClient", $VERSION;
22 root 1.1 }
23    
24 root 1.62 use utf8;
25    
26 root 1.43 use Carp ();
27 root 1.52 use AnyEvent ();
28 root 1.34 use BerkeleyDB;
29 root 1.52
30 root 1.5 sub find_rcfile($) {
31     my $path;
32    
33 root 1.46 for (grep !ref, @INC) {
34 root 1.22 $path = "$_/CFClient/resources/$_[0]";
35 root 1.5 return $path if -r $path;
36     }
37    
38     die "FATAL: can't find required file $_[0]\n";
39     }
40    
41     sub read_cfg {
42     my ($file) = @_;
43    
44     open CFG, $file
45     or return;
46    
47     my $CFG;
48    
49     local $/;
50     $CFG = eval <CFG>;
51    
52     $::CFG = $CFG;
53    
54     close CFG;
55     }
56    
57     sub write_cfg {
58     my ($file) = @_;
59    
60     open CFG, ">$file"
61     or return;
62    
63     {
64 elmex 1.9 require Data::Dumper;
65 root 1.5 local $Data::Dumper::Purity = 1;
66     $::CFG->{VERSION} = $::VERSION;
67     print CFG Data::Dumper->Dump ([$::CFG], [qw/CFG/]);
68     }
69    
70     close CFG;
71     }
72    
73 root 1.34 mkdir "$Crossfire::VARDIR/pclient", 0777;
74    
75     our $DB_ENV = new BerkeleyDB::Env
76     -Home => "$Crossfire::VARDIR/pclient",
77     -Cachesize => 1_000_000,
78 root 1.39 -ErrFile => "$Crossfire::VARDIR/pclient/errorlog.txt",
79     # -ErrPrefix => "DATABASE",
80 root 1.34 -Verbose => 1,
81 root 1.58 -Flags => DB_CREATE | DB_RECOVER | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN,
82 root 1.34 or die "unable to create/open database home $Crossfire::VARDIR/pclient: $BerkeleyDB::Error";
83    
84     sub db_table($) {
85 root 1.38 my ($table) = @_;
86    
87     $table =~ s/([^a-zA-Z0-9_\-])/sprintf "=%x=", ord $1/ge;
88    
89 root 1.34 new CFClient::Database
90     -Env => $DB_ENV,
91 root 1.38 -Filename => $table,
92     # -Filename => "database",
93     # -Subname => $table,
94 root 1.51 -Property => DB_CHKSUM,
95 root 1.34 -Flags => DB_CREATE | DB_UPGRADE,
96     or die "unable to create/open database table $_[0]: $BerkeleyDB::Error";
97     }
98    
99 root 1.52 sub pod_to_pango($) {
100     my ($pom) = @_;
101    
102     $pom->present ("CFClient::PodToPango")
103     }
104    
105 root 1.60 sub pod_to_pango_list($) {
106     my ($pom) = @_;
107    
108     [
109     map s/^(\s*)// && [40 * length $1, length $_ ? $_ : " "],
110     split /\n/, $pom->present ("CFClient::PodToPango")
111     ]
112     }
113    
114 root 1.52 package CFClient::PodToPango;
115    
116     use base Pod::POM::View::Text;
117    
118     our $indent = 0;
119    
120     *view_seq_code =
121     *view_seq_bold = sub { "<b>$_[1]</b>" };
122     *view_seq_italic = sub { "<i>$_[1]</i>" };
123     *view_seq_space =
124     *view_seq_link =
125     *view_seq_index = sub { CFClient::UI::Label::escape ($_[1]) };
126    
127     sub view_seq_text {
128     my $text = $_[1];
129     $text =~ s/\s+/ /g;
130     CFClient::UI::Label::escape ($text)
131     }
132    
133     sub view_item {
134     ("\t" x ($indent / 4))
135     . $_[1]->title->present ($_[0])
136     . "\n"
137     . $_[1]->content->present ($_[0])
138     }
139    
140 root 1.53 sub view_verbatim {
141     (join "",
142 root 1.69 map +("\t" x ($indent / 2)) . "<tt>$_</tt>\n",
143 root 1.53 split /\n/, CFClient::UI::Label::escape ($_[1]))
144     . "\n"
145     }
146    
147 root 1.52 sub view_textblock {
148     ("\t" x ($indent / 2)) . "$_[1]\n\n"
149     }
150    
151 root 1.60 sub view_head1 {
152 root 1.69 "\n\n<span foreground='#ffff00' size='x-large'>" . $_[1]->title->present ($_[0]) . "</span>\n\n"
153 root 1.60 . $_[1]->content->present ($_[0])
154     };
155    
156 root 1.52 sub view_head2 {
157 root 1.69 "\n<span foreground='#ccccff' size='large'>" . $_[1]->title->present ($_[0]) . "</span>\n\n"
158     . $_[1]->content->present ($_[0])
159     };
160    
161     sub view_head3 {
162     "\n<span size='large'>" . $_[1]->title->present ($_[0]) . "</span>\n\n"
163 root 1.52 . $_[1]->content->present ($_[0])
164     };
165    
166     sub view_over {
167     local $indent = $indent + $_[1]->indent;
168     $_[1]->content->present ($_[0])
169     }
170    
171 root 1.34 package CFClient::Database;
172    
173     our @ISA = BerkeleyDB::Btree::;
174    
175     sub get($$) {
176     my $data;
177    
178     $_[0]->db_get ($_[1], $data) == 0
179     ? $data
180 root 1.37 : ()
181 root 1.34 }
182    
183     my %DB_SYNC;
184    
185     sub put($$$) {
186     my ($db, $key, $data) = @_;
187    
188 root 1.37 $DB_SYNC{$db} = AnyEvent->timer (after => 5, cb => sub { $db->db_sync });
189 root 1.34
190 root 1.37 $db->db_put ($key => $data)
191 root 1.34 }
192    
193 root 1.62 package CFClient::Item;
194    
195 root 1.71 use strict;
196     use Crossfire::Protocol::Constants;
197    
198 root 1.62 sub desc_string {
199     my ($self) = @_;
200    
201     my $desc =
202     $self->{nrof} < 2
203     ? $self->{name}
204     : "$self->{nrof} × $self->{name_pl}";
205    
206 root 1.71 $self->{flags} & F_OPEN
207 root 1.62 and $desc .= " (open)";
208 root 1.71 $self->{flags} & F_APPLIED
209 root 1.62 and $desc .= " (applied)";
210 root 1.71 $self->{flags} & F_UNPAID
211 root 1.62 and $desc .= " (unpaid)";
212 root 1.71 $self->{flags} & F_MAGIC
213 root 1.62 and $desc .= " (magic)";
214 root 1.71 $self->{flags} & F_CURSED
215 root 1.62 and $desc .= " (cursed)";
216 root 1.71 $self->{flags} & F_DAMNED
217 root 1.62 and $desc .= " (damned)";
218 root 1.71 $self->{flags} & F_LOCKED
219 root 1.62 and $desc .= " *";
220    
221     $desc
222     }
223    
224     sub weight_string {
225     my ($self) = @_;
226    
227     my $weight = ($self->{nrof} || 1) * $self->{weight};
228    
229     $weight < 0 ? "?" : $weight * 0.001
230     }
231    
232     sub update_widgets {
233     my ($self) = @_;
234    
235 root 1.63 my $button_cb = sub {
236     my (undef, $ev, $x, $y) = @_;
237    
238     if (($ev->{mod} & CFClient::KMOD_SHIFT) && $ev->{button} == 1) {
239     my $targ = $::CONN->{player}{tag};
240    
241     if ($self->{container} == $::CONN->{player}{tag}) {
242 elmex 1.64 $targ = $::CONN->{open_container};
243 root 1.63 }
244    
245     $::CONN->send ("move $targ $self->{tag} 0");
246     } elsif ($ev->{button} == 1) {
247     $::CONN->send ("examine $self->{tag}");
248     } elsif ($ev->{button} == 2) {
249     $::CONN->send ("apply $self->{tag}");
250     } elsif ($ev->{button} == 3) {
251     my @menu_items = (
252     ["examine", sub { $::CONN->send ("examine $self->{tag}") }],
253     ["mark", sub { $::CONN->send ("mark ". pack "N", $self->{tag}) }],
254     ["apply", sub { $::CONN->send ("apply $self->{tag}") }],
255     (
256 root 1.71 $self->{flags} & F_LOCKED
257 root 1.63 ? (
258     ["unlock", sub { $::CONN->send ("lock " . pack "CN", 0, $self->{tag}) }],
259     )
260     : (
261     ["lock", sub { $::CONN->send ("lock " . pack "CN", 1, $self->{tag}) }],
262 elmex 1.64 ["drop", sub { $::CONN->send ("move $::CONN->{open_container} $self->{tag} 0") }],
263 root 1.63 )
264     ),
265     );
266    
267     CFClient::UI::Menu->new (items => \@menu_items)->popup ($ev);
268     }
269    
270     1
271     };
272    
273 root 1.62 my $tooltip_std = "<small>"
274     . "Left click - examine item\n"
275     . "Shift-Left click - " . ($self->{container} ? "move or drop" : "take") . " item\n"
276     . "Middle click - apply\n"
277     . "Right click - further options"
278     . "</small>\n";
279    
280 root 1.63 $self->{face_widget} ||= new CFClient::UI::Face
281     can_events => 1,
282     can_hover => 1,
283 root 1.67 anim => $self->{anim},
284 root 1.66 animspeed => $self->{animspeed}, # TODO# must be set at creation time
285 root 1.72 on_button_down => $button_cb,
286 root 1.63 ;
287 root 1.62 $self->{face_widget}{face} = $self->{face};
288     $self->{face_widget}{anim} = $self->{anim};
289 root 1.65 $self->{face_widget}{animspeed} = $self->{animspeed};
290 root 1.62 $self->{face_widget}->set_tooltip (
291     "<b>Face/Animation.</b>\n"
292     . "Item uses face #$self->{face}. "
293     . ($self->{animspeed} ? "Item uses animation #$self->{anim} at " . (1 / $self->{animspeed}) . "fps. " : "Item is not animated. ")
294     . "\n\n$tooltip_std"
295     );
296    
297 root 1.63 $self->{desc_widget} ||= new CFClient::UI::Label
298     can_events => 1,
299     can_hover => 1,
300     ellipsise => 2,
301 root 1.68 align => -1,
302 root 1.72 on_button_down => $button_cb,
303 root 1.63 ;
304     my $desc = CFClient::Item::desc_string $self;
305     $self->{desc_widget}->set_text ($desc);
306     $self->{desc_widget}->set_tooltip ("<b>$desc</b>.\n$tooltip_std");
307    
308     $self->{weight_widget} ||= new CFClient::UI::Label
309     can_events => 1,
310     can_hover => 1,
311     ellipsise => 0,
312 root 1.68 align => 0,
313 root 1.72 on_button_down => $button_cb,
314 root 1.63 ;
315 root 1.62 $self->{weight_widget}->set_text (CFClient::Item::weight_string $self);
316    
317     $self->{weight_widget}->set_tooltip (
318     "<b>Weight</b>.\n"
319     . ($self->{weight} >= 0 ? "One item weighs $self->{weight}g. " : "You have no idea how much this weighs. ")
320     . ($self->{nrof} ? "You have $self->{nrof} of it. " : "Item cannot stack with others of it's kind. ")
321     . "\n\n$tooltip_std"
322     );
323     }
324    
325 root 1.1 1;
326    
327     =back
328    
329     =head1 AUTHOR
330    
331     Marc Lehmann <schmorp@schmorp.de>
332     http://home.schmorp.de/
333    
334     =cut
335