ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/map_lib.ext
Revision: 1.8
Committed: Sat Mar 20 16:30:24 2010 UTC (14 years, 2 months ago) by elmex
Branch: MAIN
Changes since 1.7: +97 -0 lines
Log Message:
fixed mana fountain unbalancement.

File Contents

# User Rev Content
1 elmex 1.1 #! perl
2    
3     =head1 CF+ map maker library and utilities
4    
5     =over 4
6    
7     =cut
8     # This extension loads some nice functionality for map makers
9    
10     sub rec_inv_by_slaying {
11     my ($ob, $slaying, $cb) = @_;
12     $cb->($ob) if $ob->slaying eq $slaying;
13     for my $iob ($ob->inv) { rec_inv_by_slaying ($iob, $slaying, $cb) }
14     }
15    
16 elmex 1.7 =item count_linked ($map, $connected)
17    
18     Counts the number of objects with the connected value C<$connected> on
19     the map C<$map>.
20    
21     =cut
22    
23     sub count_linked {
24     my ($map, $connected) = @_;
25     my (@a) = $map->find_link ($connected);
26     scalar @a
27     }
28    
29 elmex 1.1 =item object attachment: 'check_inventory_on_apply'
30    
31     This attachment checks on apply whether the applyer
32     has a specific item. Currently you can only match the slaying
33     field of the inventory item of the player.
34    
35     On match the apply isn't inhibited.
36    
37     Following configuration can be supplied to this attachment:
38    
39     =over 4
40    
41     =item key_string
42    
43     This is the string that will be matched against the slaying field
44     of the inventory item of the player. The first found item will be
45     decreased by the amount that can be passed in the 'decrease_by_cnt'
46     option.
47    
48     =item decrease_by_cnt
49    
50     This is the amount the matching object will be decreased by from the inventory.
51     Default is 0 and means nothing will be removed.
52    
53     =item message_on_match
54    
55     This is the message that will printed to the player if a matching
56     object was found.
57    
58     =item message_on_nomatch
59    
60     This is the message that will printed to the player if NO matching
61     object was found.
62    
63     =back
64    
65     =cut
66    
67 root 1.3 cf::object::attachment check_inventory_on_apply =>
68 elmex 1.1 on_apply => sub {
69     my ($self, $pl) = @_;
70     my $cfg = $self->{check_inventory_on_apply};
71     my $match;
72     rec_inv_by_slaying ($pl, $cfg->{key_string}, sub {
73     my ($ob) = @_;
74     $match = $ob;
75     });
76     if ($match) {
77 root 1.6 $match->decrease ($cfg->{decrease_by_cnt}) if $cfg->{decrease_by_cnt};
78 elmex 1.2 $pl->message ($cfg->{message_on_match}, cf::NDI_UNIQUE) if defined $cfg->{message_on_match};
79 elmex 1.1 } else {
80 elmex 1.2 $pl->message ($cfg->{message_on_nomatch}, cf::NDI_RED | cf::NDI_UNIQUE) if defined $cfg->{message_on_nomatch};
81 elmex 1.1 cf::override;
82     }
83     };
84    
85 elmex 1.4
86     =item object attachment: 'trigger_on_dialog_flag'
87    
88     This attachment checks whether the player has a specific
89     dialog flag set (the ones you can set with @setflag, see also
90     L<NPC_Dialogue>, and triggers a connection depending on that.
91    
92     The attachment has following configuration:
93    
94     =over 4
95    
96     =item flag
97    
98     This field should contain the name of the flag that you want to check
99     for.
100    
101     =item connection
102    
103     The connection ID of the connection you want to trigger.
104    
105     =item state
106    
107     The state of the connection: 0 for release, 1 for push.
108    
109     =back
110    
111     =cut
112    
113     cf::object::attachment trigger_on_dialog_flag =>
114     on_move_trigger => sub {
115     my ($self, $who, $orig) = @_;
116     my $cfg = $self->{trigger_on_dialog_flag};
117     if (exists $who->{ob}{dialog_flag}{$cfg->{flag}}) {
118     if ($who->{ob}{dialog_flag}{$cfg->{flag}}) {
119     $self->map->trigger ($cfg->{connection}, $cfg->{state});
120     }
121     cf::override;
122     }
123     };
124    
125 elmex 1.8
126     =item object attachment: 'ratelimit_converter'
127    
128     This is an attachment that allows a converter to be ratelimited in terms of
129     items per hour.
130    
131     The attachment has following configuration:
132    
133     =over 4
134    
135     =item match
136    
137     This field should contain a L<cf::match> match string, that should match the
138     input object.
139    
140     =item generate_arch
141    
142     This field should contain the archetype name of the output.
143    
144     =item items_per_hour
145    
146     This field should contain the number of items to generate at maximum per hour.
147     Default is: 20
148    
149     =item converter_tag
150    
151     This is the tag of the converter, it should be unique per converter. You can
152     also use this to make the limit hit for multiple converters.
153    
154     =item msg
155    
156     This is the message when the player successfully converted.
157    
158     =item failmsg
159    
160     This is the failure message, which will be presented to the player when he hits
161     the rate limit.
162    
163     =back
164    
165     =cut
166    
167     cf::object::attachment ratelimit_converter =>
168     on_drop_on => sub {
169     my ($self, $obj, $who) = @_;
170    
171     my $cfg = $self->{ratelimit_converter};
172    
173     my $output_arch = $cfg->{generate_arch};
174     my $match = $cfg->{match};
175     my $mitems = $cfg->{items_per_hour} || 20;
176     my $tag = 'ratelimit_converter_' . $cfg->{converter_tag};
177    
178     return unless cf::match::match $match, $obj;
179    
180     my $items = $mitems;
181    
182     if (!$who->flag (cf::FLAG_WIZ) && defined $who->{$tag . '_ts'}) {
183     my $itemtime = time - $who->{$tag . '_ts'};
184     if ($itemtime < 3600) {
185     $items = int ($items * ($itemtime / 3600));
186     }
187     }
188    
189     my $nr = $obj->nrof ? $obj->nrof : 1;
190     $nr = $items if $nr > $items;
191    
192     if ($nr > 0) {
193     $obj->decrease ($nr);
194    
195     my $out = cf::object::new ($output_arch);
196     $out->nrof ($nr);
197     $out->insert_at ($self, $self);
198    
199     if ($nr >= $mitems) {
200     $who->{$tag . '_ts'} = time;
201     } else {
202     # give player credit for the unused refills.
203     $who->{$tag . '_ts'} =
204     time - int ((($items - $nr) * 3600) / $mitems);
205     }
206    
207     $who->message ($cfg->{msg})
208     if $cfg->{msg} ne '';
209     } else {
210     if ($who->contr) {
211     $who->contr->failmsg ($cfg->{failmsg})
212     if $cfg->{failmsg} ne '';
213     }
214     }
215    
216     if ($who->flag (cf::FLAG_WIZ)) {
217     delete $who->{$tag . '_ts'};
218     }
219     };
220    
221    
222 elmex 1.5 =item object attachment: 'display_info_window'
223    
224     If you attach this attachment to a sign a window containing the
225     message will open in the client when the player applies it.
226    
227     Use this feature with care, as popups usually are very noisy.
228     This is mostly thought for tutorial or other instructions.
229    
230     =cut
231    
232     cf::object::attachment display_info_window =>
233     on_apply => sub {
234     my ($self, $pl) = @_;
235    
236     return unless $pl->contr->ns->{can_widget};
237    
238     my $cfg = $self->{display_info_window};
239    
240     if ($pl->contr->ns->{info_wins}->{$self->uuid}) {
241     $pl->contr->ns->{info_wins}->{$self->uuid}->destroy;
242     }
243    
244     my $ws = $pl->contr->ns->new_widgetset;
245    
246     my $w = $ws->{my_main} = $ws->new (Toplevel =>
247     force_w => 600,
248     force_h => 400,
249     x => 'center',
250     y => 'center',
251     title => 'Information Sign',
252     has_close_button => 1,
253     on_delete => sub { $ws->destroy },
254     );
255     $w->add ($ws->{txt_area} = $ws->new ('TextScroller'));
256     $ws->{txt_area}->add_paragraph ($self->msg);
257     $w->show;
258     $pl->contr->ns->{info_wins}->{$self->uuid} = $ws;
259    
260     cf::override 1;
261     };
262    
263 elmex 1.1 =back
264    
265     =cut