ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/DC/Item.pm
Revision: 1.19
Committed: Wed Nov 21 13:23:10 2012 UTC (11 years, 5 months ago) by root
Branch: MAIN
CVS Tags: HEAD
Changes since 1.18: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 package DC::Item;
2
3 use common::sense;
4
5 use Deliantra::Protocol::Constants;
6
7 my $last_enter_count = 1;
8
9 sub desc_string {
10 my ($self) = @_;
11
12 my $desc =
13 $self->{nrof} < 2
14 ? $self->{name}
15 : "$self->{nrof} $self->{name_pl}";
16
17 $self->{flags} & F_OPEN
18 and $desc .= " (open)";
19 $self->{flags} & F_APPLIED
20 and $desc .= " (applied)";
21 $self->{flags} & F_UNPAID
22 and $desc .= " (unpaid)";
23 $self->{flags} & F_MAGIC
24 and $desc .= " (magic)";
25 $self->{flags} & F_CURSED
26 and $desc .= " (cursed)";
27 $self->{flags} & F_DAMNED
28 and $desc .= " (damned)";
29 $self->{flags} & F_LOCKED
30 and $desc .= " *";
31
32 $desc
33 }
34
35 sub weight_string {
36 my ($self) = @_;
37
38 my $weight = ($self->{nrof} || 1) * $self->{weight};
39
40 $weight < 0 ? "?" : $weight * 0.001
41 }
42
43 sub do_n_dialog {
44 my ($cb) = @_;
45
46 my $w = new DC::UI::Toplevel
47 on_delete => sub { $_[0]->destroy; 1 },
48 has_close_button => 1,
49 ;
50
51 $w->add (my $vb = new DC::UI::VBox x => "center", y => "center");
52 $vb->add (new DC::UI::Label text => "Enter item count:");
53 $vb->add (my $entry = new DC::UI::Entry
54 text => $last_enter_count,
55 on_activate => sub {
56 my ($entry) = @_;
57 $last_enter_count = $entry->get_text;
58 $cb->($last_enter_count);
59 $w->hide;
60 $w->destroy;
61
62 0
63 },
64 on_escape => sub { $w->destroy; 1 },
65 );
66 $entry->grab_focus;
67 $w->show;
68 }
69
70 my $bg_cursed = [1 , 0 , 0, 0.5];
71 my $bg_magic = [0.2, 0.2, 1, 0.5];
72
73 sub update_widgets {
74 my ($self) = @_;
75
76 # necessary to avoid cyclic references
77 DC::weaken $self;
78
79 my $button_cb = sub {
80 my (undef, $ev, $x, $y) = @_;
81
82 my $targ = $::CONN->{player}{tag};
83
84 if ($self->{container} == $::CONN->{player}{tag}) {
85 $targ = $::CONN->{open_container};
86 }
87
88 if (($ev->{mod} & DC::KMOD_SHIFT) && $ev->{button} == 1) {
89 $::CONN->send ("move $targ $self->{tag} 0")
90 if $targ || !($self->{flags} & F_LOCKED);
91 } elsif (($ev->{mod} & DC::KMOD_SHIFT) && $ev->{button} == 2) {
92 $self->{flags} & F_LOCKED
93 ? $::CONN->send ("lock " . pack "CN", 0, $self->{tag})
94 : $::CONN->send ("lock " . pack "CN", 1, $self->{tag})
95 } elsif ($ev->{button} == 1) {
96 $::CONN->send ("examine $self->{tag}");
97 } elsif ($ev->{button} == 2) {
98 $::CONN->send ("apply $self->{tag}");
99 } elsif ($ev->{button} == 3) {
100 my $move_prefix = $::CONN->{open_container} ? 'put' : 'drop';
101 if ($self->{container} == $::CONN->{open_container}) {
102 $move_prefix = "take";
103 }
104
105 my $shortname = DC::shorten $self->{name}, 14;
106
107 my @menu_items = (
108 ["examine", sub { $::CONN->send ("examine $self->{tag}") }],
109 ["mark", sub { $::CONN->send ("mark ". pack "N", $self->{tag}) }],
110 ["ignite/thaw", # first try of an easier use of flint&steel
111 sub {
112 $::CONN->send ("mark ". pack "N", $self->{tag});
113 $::CONN->send ("command apply flint and steel");
114 }
115 ],
116 ["inscribe", # first try of an easier use of flint&steel
117 sub {
118 &::open_string_query ("Text to inscribe", sub {
119 my ($entry, $txt) = @_;
120 $::CONN->send ("mark ". pack "N", $self->{tag});
121 $::CONN->send_utf8 ("command use_skill inscription $txt");
122 });
123 }
124 ],
125 ["rename", # first try of an easier use of flint&steel
126 sub {
127 &::open_string_query ("Rename item to:", sub {
128 my ($entry, $txt) = @_;
129 $::CONN->send ("mark ". pack "N", $self->{tag});
130 $::CONN->send_utf8 ("command rename to <$txt>");
131 }, $self->{name},
132 "If you input no name or erase the current custom name, the custom name will be unset");
133 }
134 ],
135 ["apply", sub { $::CONN->send ("apply $self->{tag}") }],
136 (
137 $self->{flags} & F_LOCKED
138 ? (
139 ["unlock", sub { $::CONN->send ("lock " . pack "CN", 0, $self->{tag}) }],
140 )
141 : (
142 ["lock", sub { $::CONN->send ("lock " . pack "CN", 1, $self->{tag}) }],
143 ["$move_prefix all", sub { $::CONN->send ("move $targ $self->{tag} 0") }],
144 ["$move_prefix &lt;n&gt;",
145 sub {
146 do_n_dialog (sub { $::CONN->send ("move $targ $self->{tag} $_[0]") })
147 }
148 ]
149 )
150 ),
151 ["bind <i>apply $shortname</i> to a key" => sub { DC::Macro::quick_macro ["apply $self->{name}"] }],
152 );
153
154 DC::UI::Menu->new (items => \@menu_items)->popup ($ev);
155 }
156
157 1
158 };
159
160 my $tooltip_std =
161 "<small>"
162 . "Left click - examine item\n"
163 . "Shift-Left click - " . ($self->{container} ? "move or drop" : "take") . " item\n"
164 . "Middle click - apply\n"
165 . "Shift-Middle click - lock/unlock\n"
166 . "Right click - further options"
167 . "</small>\n";
168
169 my $bg = $self->{flags} & F_CURSED ? $bg_cursed
170 : $self->{flags} & F_MAGIC ? $bg_magic
171 : undef;
172
173 my $desc = DC::Item::desc_string $self;
174 my $face_tooltip = "<b>$desc</b>\n\n$tooltip_std";
175
176 if (my $face = $self->{face_widget}) {
177 # already exists, so update if it changed
178 if ($face->{bg} != $bg) {
179 $face->{bg} = $bg;
180 $face->update;
181 }
182
183 $face->set_bg ($bg) if $face->{bg} != $bg;
184 $face->set_face ($self->{face}) if $face->{face} != $self->{face};
185 $face->set_anim ($self->{anim}) if $face->{anim} != $self->{anim};
186 $face->set_animspeed ($self->{animspeed}) if $face->{animspeed} != $self->{animspeed};
187
188 #$face->set_tooltip (
189 # "<b>Face/Animation.</b>\n"
190 # . "Item uses face #$self->{face}. "
191 # . ($self->{animspeed} ? "Item uses animation #$self->{anim} at " . (1 / $self->{animspeed}) . "fps. " : "Item is not animated. ")
192 # . "\n\n$tooltip_std"
193 #);
194 $face->set_tooltip ($face_tooltip);
195 } else {
196 # new object, create new face
197 $self->{face_widget} = new DC::UI::Face
198 can_events => 1,
199 can_hover => 1,
200 bg => $bg,
201 face => $self->{face},
202 anim => $self->{anim},
203 animspeed => $self->{animspeed}, # TODO# must be set at creation time
204 tooltip => $face_tooltip,
205 on_button_down => $button_cb,
206 ;
207 }
208
209 $self->{desc_widget} ||= new DC::UI::Label
210 can_events => 1,
211 can_hover => 1,
212 ellipsise => 2,
213 align => 0,
214
215 on_button_down => $button_cb,
216 on_tooltip_show => sub {
217 my ($widget) = @_;
218
219 $::CONN && $::CONN->ex ($self->{tag}, sub {
220 my ($long_desc) = @_;
221
222 $long_desc = DC::sanitise_cfxml ($long_desc);
223
224 $self->{long_desc} = $long_desc;
225 $widget->set_tooltip ("<b>$long_desc</b>\n\n$tooltip_std");
226 });
227 },
228 ;
229
230 my $long_desc = $self->{long_desc} || $desc;
231
232 $self->{desc_widget}->set_bg ($bg) if $self->{desc_widget}{bg} != $bg;
233 $self->{desc_widget}->set_text ($desc);
234 $self->{desc_widget}->set_tooltip ("<b>$long_desc</b>\n\n$tooltip_std");
235
236 $self->{weight_widget} ||= new DC::UI::Label
237 can_events => 1,
238 can_hover => 1,
239 ellipsise => 0,
240 on_button_down => $button_cb,
241 ;
242 $self->{weight_widget}{bg} = $bg;
243 $self->{weight_widget}->set_text (DC::Item::weight_string $self);
244 $self->{weight_widget}->set_tooltip (
245 "<b>Weight</b>.\n"
246 . ($self->{weight} >= 0 ? "One item weighs $self->{weight}g. " : "You have no idea how much this weighs. ")
247 . ($self->{nrof} ? "You have $self->{nrof} of it. " : "Item cannot stack with others of it's kind. ")
248 . "\n\n$tooltip_std"
249 );
250 }
251