--- deliantra/server/ext/map_lib.ext 2007/02/05 11:48:43 1.4 +++ deliantra/server/ext/map_lib.ext 2010/03/20 16:30:24 1.8 @@ -13,6 +13,19 @@ for my $iob ($ob->inv) { rec_inv_by_slaying ($iob, $slaying, $cb) } } +=item count_linked ($map, $connected) + +Counts the number of objects with the connected value C<$connected> on +the map C<$map>. + +=cut + +sub count_linked { + my ($map, $connected) = @_; + my (@a) = $map->find_link ($connected); + scalar @a +} + =item object attachment: 'check_inventory_on_apply' This attachment checks on apply whether the applyer @@ -61,7 +74,7 @@ $match = $ob; }); if ($match) { - $match->decrease_ob_nr ($cfg->{decrease_by_cnt}) if $cfg->{decrease_by_cnt}; + $match->decrease ($cfg->{decrease_by_cnt}) if $cfg->{decrease_by_cnt}; $pl->message ($cfg->{message_on_match}, cf::NDI_UNIQUE) if defined $cfg->{message_on_match}; } else { $pl->message ($cfg->{message_on_nomatch}, cf::NDI_RED | cf::NDI_UNIQUE) if defined $cfg->{message_on_nomatch}; @@ -109,6 +122,144 @@ } }; + +=item object attachment: 'ratelimit_converter' + +This is an attachment that allows a converter to be ratelimited in terms of +items per hour. + +The attachment has following configuration: + +=over 4 + +=item match + +This field should contain a L match string, that should match the +input object. + +=item generate_arch + +This field should contain the archetype name of the output. + +=item items_per_hour + +This field should contain the number of items to generate at maximum per hour. +Default is: 20 + +=item converter_tag + +This is the tag of the converter, it should be unique per converter. You can +also use this to make the limit hit for multiple converters. + +=item msg + +This is the message when the player successfully converted. + +=item failmsg + +This is the failure message, which will be presented to the player when he hits +the rate limit. + +=back + +=cut + +cf::object::attachment ratelimit_converter => + on_drop_on => sub { + my ($self, $obj, $who) = @_; + + my $cfg = $self->{ratelimit_converter}; + + my $output_arch = $cfg->{generate_arch}; + my $match = $cfg->{match}; + my $mitems = $cfg->{items_per_hour} || 20; + my $tag = 'ratelimit_converter_' . $cfg->{converter_tag}; + + return unless cf::match::match $match, $obj; + + my $items = $mitems; + + if (!$who->flag (cf::FLAG_WIZ) && defined $who->{$tag . '_ts'}) { + my $itemtime = time - $who->{$tag . '_ts'}; + if ($itemtime < 3600) { + $items = int ($items * ($itemtime / 3600)); + } + } + + my $nr = $obj->nrof ? $obj->nrof : 1; + $nr = $items if $nr > $items; + + if ($nr > 0) { + $obj->decrease ($nr); + + my $out = cf::object::new ($output_arch); + $out->nrof ($nr); + $out->insert_at ($self, $self); + + if ($nr >= $mitems) { + $who->{$tag . '_ts'} = time; + } else { + # give player credit for the unused refills. + $who->{$tag . '_ts'} = + time - int ((($items - $nr) * 3600) / $mitems); + } + + $who->message ($cfg->{msg}) + if $cfg->{msg} ne ''; + } else { + if ($who->contr) { + $who->contr->failmsg ($cfg->{failmsg}) + if $cfg->{failmsg} ne ''; + } + } + + if ($who->flag (cf::FLAG_WIZ)) { + delete $who->{$tag . '_ts'}; + } + }; + + +=item object attachment: 'display_info_window' + +If you attach this attachment to a sign a window containing the +message will open in the client when the player applies it. + +Use this feature with care, as popups usually are very noisy. +This is mostly thought for tutorial or other instructions. + +=cut + +cf::object::attachment display_info_window => + on_apply => sub { + my ($self, $pl) = @_; + + return unless $pl->contr->ns->{can_widget}; + + my $cfg = $self->{display_info_window}; + + if ($pl->contr->ns->{info_wins}->{$self->uuid}) { + $pl->contr->ns->{info_wins}->{$self->uuid}->destroy; + } + + my $ws = $pl->contr->ns->new_widgetset; + + my $w = $ws->{my_main} = $ws->new (Toplevel => + force_w => 600, + force_h => 400, + x => 'center', + y => 'center', + title => 'Information Sign', + has_close_button => 1, + on_delete => sub { $ws->destroy }, + ); + $w->add ($ws->{txt_area} = $ws->new ('TextScroller')); + $ws->{txt_area}->add_paragraph ($self->msg); + $w->show; + $pl->contr->ns->{info_wins}->{$self->uuid} = $ws; + + cf::override 1; + }; + =back =cut