… | |
… | |
21 | =cut |
21 | =cut |
22 | |
22 | |
23 | our $CFG; |
23 | our $CFG; |
24 | |
24 | |
25 | sub load_config { |
25 | sub load_config { |
|
|
26 | cf::trace "loading jeweler config from $cf::DATADIR/jeweler\n"; |
|
|
27 | |
26 | 0 < Coro::AIO::aio_load "$cf::DATADIR/jeweler", my $data |
28 | 0 < Coro::AIO::aio_load "$cf::DATADIR/jeweler", my $data |
27 | or die "$cf::DATADIR/jeweler: $!"; |
29 | or die "$cf::DATADIR/jeweler: $!"; |
28 | |
30 | |
29 | $CFG = cf::decode_json $data; |
31 | $CFG = cf::decode_json $data; |
30 | } |
32 | } |
… | |
… | |
168 | next; |
170 | next; |
169 | } |
171 | } |
170 | $found = 1; |
172 | $found = 1; |
171 | my $r = Jeweler::Object->new (object => $_); |
173 | my $r = Jeweler::Object->new (object => $_); |
172 | my $msg = $r->analyze ($sk, $pl, $input_level); |
174 | my $msg = $r->analyze ($sk, $pl, $input_level); |
173 | $pl->message ($r->to_string . ": " . $msg); |
175 | $pl->message ("There is a '" . $r->to_string . "' in the workbench. Your analysis: " . $msg); |
174 | if ($pl->flag (cf::FLAG_WIZ)) { |
176 | if ($pl->flag (cf::FLAG_WIZ)) { |
175 | $r->wiz_analyze ($pl); |
177 | $r->wiz_analyze ($pl); |
176 | } |
178 | } |
177 | } |
179 | } |
178 | $pl->message ("You couldn't identify the other rings and not analyze them!") |
180 | $pl->message ("You couldn't identify the other rings and not analyze them!") |
… | |
… | |
228 | if ($nrof) { |
230 | if ($nrof) { |
229 | # XXX: yes, I know what I'm doing here, I don't set nrof, but it didn't work somehow (pls. check sometimes) |
231 | # XXX: yes, I know what I'm doing here, I don't set nrof, but it didn't work somehow (pls. check sometimes) |
230 | $ingred->remove ($ingr_grp, $srcarchname); |
232 | $ingred->remove ($ingr_grp, $srcarchname); |
231 | for (1 .. $nrof) { |
233 | for (1 .. $nrof) { |
232 | $chdl->put (my $ob = cf::object::new $outarch); |
234 | $chdl->put (my $ob = cf::object::new $outarch); |
233 | $ob->set_animation (cf::rndm $ob->num_animations) |
235 | $ob->set_anim_frame (cf::rndm $ob->anim_frames) |
234 | if ($ob->type == cf::RING); |
236 | if ($ob->type == cf::RING); |
235 | $ob->flag (cf::FLAG_IDENTIFIED, 1); |
237 | $ob->flag (cf::FLAG_IDENTIFIED, 1); |
236 | } |
238 | } |
237 | |
239 | |
238 | my $xp_sum = $xp_gain * $nrof; |
240 | my $xp_sum = $xp_gain * $nrof; |
… | |
… | |
247 | } |
249 | } |
248 | |
250 | |
249 | |
251 | |
250 | package Jeweler::CauldronHandler; |
252 | package Jeweler::CauldronHandler; |
251 | |
253 | |
252 | use strict; |
254 | use common::sense; |
253 | |
255 | |
254 | =head2 CauldronHandler |
256 | =head2 CauldronHandler |
255 | |
257 | |
256 | The Jeweler::CauldronHandler package, that helps you with handling the |
258 | The Jeweler::CauldronHandler package, that helps you with handling the |
257 | cauldron stuff. Can also be used for other skills. |
259 | cauldron stuff. Can also be used for other skills. |
… | |
… | |
365 | =back |
367 | =back |
366 | |
368 | |
367 | =cut |
369 | =cut |
368 | |
370 | |
369 | package Jeweler::Ingredients; |
371 | package Jeweler::Ingredients; |
|
|
372 | |
|
|
373 | use common::sense; |
|
|
374 | |
370 | use Storable qw/dclone/; |
375 | use Storable qw/dclone/; |
371 | use strict; |
|
|
372 | |
376 | |
373 | =head2 Ingredients |
377 | =head2 Ingredients |
374 | |
378 | |
375 | This class handles the ingredients. |
379 | This class handles the ingredients. |
376 | |
380 | |
… | |
… | |
587 | } |
591 | } |
588 | |
592 | |
589 | if ($do_remove) { |
593 | if ($do_remove) { |
590 | my $rem = $costs->{$key}; |
594 | my $rem = $costs->{$key}; |
591 | $self->do_grep (sub { |
595 | $self->do_grep (sub { |
|
|
596 | if ($rem) { |
592 | if ($rem) { $rem = Jeweler::Util::remove ($_[0], $rem); } |
597 | $rem = Jeweler::Util::remove ($_[0], $rem); |
|
|
598 | } |
593 | 1 |
599 | 1 |
594 | }, @grepar); |
600 | }, @grepar); |
595 | if ($rem > 0) { |
601 | if ($rem > 0) { |
596 | warn "JEWELER BUG: removed ingredients ($key) $rem > 0 after removing!"; |
602 | warn "JEWELER BUG: removed ingredients ($key) $rem > 0 after removing!"; |
597 | } |
603 | } |
… | |
… | |
622 | } |
628 | } |
623 | } |
629 | } |
624 | } |
630 | } |
625 | |
631 | |
626 | package Jeweler::Object; |
632 | package Jeweler::Object; |
627 | use strict; |
633 | |
|
|
634 | use common::sense; |
628 | use POSIX; |
635 | use POSIX; |
629 | use List::Util qw/max min sum/; |
636 | use List::Util qw/max min sum/; |
630 | |
637 | |
631 | sub new { |
638 | sub new { |
632 | my ($class, %arg) = @_; |
639 | my ($class, %arg) = @_; |
… | |
… | |
647 | return 1 if $self->{hash}->{resist}->{$resnum}; |
654 | return 1 if $self->{hash}->{resist}->{$resnum}; |
648 | } |
655 | } |
649 | return undef; |
656 | return undef; |
650 | } |
657 | } |
651 | |
658 | |
|
|
659 | sub lvl2exp { |
|
|
660 | my $lvl = shift; |
|
|
661 | (cf::level_to_min_exp ($lvl) - cf::level_to_min_exp ($lvl - 1)) |
|
|
662 | / (20 + max ($lvl - 1, 0)) # 20 + level times making such a ring |
|
|
663 | # should get you to the rings level at least. |
|
|
664 | } |
|
|
665 | |
652 | sub projected_exp { |
666 | sub projected_exp { |
653 | my ($self, $input_level) = @_; |
667 | my ($self, $input_level) = @_; |
654 | |
668 | |
655 | my $lvl = max ($self->power_to_level, 1); |
669 | my $lvl = max ($self->power_to_level, 1); |
656 | my $exp = |
670 | my $exp = lvl2exp ($lvl); |
657 | (cf::level_to_min_exp ($lvl) - cf::level_to_min_exp ($lvl - 1)) |
|
|
658 | / (10 + max ($lvl - 1, 0)); # 10 + level times making such a ring |
|
|
659 | # should get you to the rings level at least. |
|
|
660 | |
671 | |
661 | if (defined $input_level) { |
672 | if (defined $input_level) { # in case we merge rings: |
662 | my $subexp = |
673 | my $subexp = lvl2exp ($input_level); |
663 | (cf::level_to_min_exp ($input_level) |
|
|
664 | - cf::level_to_min_exp ($input_level - 1)) |
|
|
665 | / (10 + max ($input_level - 1, 0)); # see above for comment |
|
|
666 | |
|
|
667 | $exp -= $subexp; |
674 | $exp -= $subexp; |
668 | $exp = max ($exp, 0); |
675 | $exp = max ($exp, 0); |
669 | |
676 | |
670 | } else { |
677 | } else { |
671 | # the experience bonus here is to make level 1 rings give you at least |
678 | # the experience bonus here is to make level 1 rings give you at least |
… | |
… | |
851 | sub to_object { |
858 | sub to_object { |
852 | my ($self) = @_; |
859 | my ($self) = @_; |
853 | |
860 | |
854 | my $obj = cf::object::new $self->{hash}->{arch}; |
861 | my $obj = cf::object::new $self->{hash}->{arch}; |
855 | |
862 | |
856 | $obj->item_power (floor ($self->power_to_level / 3)); # there have to be strings attached! |
863 | $obj->item_power (floor ($self->power_to_level / 5)); # there have to be strings attached! |
857 | |
864 | |
858 | $obj->face ($self->{hash}{face}); |
865 | $obj->face ($self->{hash}{face}); |
859 | |
866 | |
860 | my $stats = $obj->stats; |
867 | my $stats = $obj->stats; |
861 | |
868 | |
… | |
… | |
1104 | $cost->{gem} += ceil $sumvalue * $stat_split->[4] / max 1, $diarch->value; |
1111 | $cost->{gem} += ceil $sumvalue * $stat_split->[4] / max 1, $diarch->value; |
1105 | } |
1112 | } |
1106 | |
1113 | |
1107 | package Jeweler::Util; |
1114 | package Jeweler::Util; |
1108 | |
1115 | |
1109 | use strict; |
1116 | use common::sense; |
1110 | |
1117 | |
1111 | =head2 Util |
1118 | =head2 Util |
1112 | |
1119 | |
1113 | Some utility functions for the Jeweler skill. |
1120 | Some utility functions for the Jeweler skill. |
1114 | |
1121 | |
… | |
… | |
1121 | |
1128 | |
1122 | =cut |
1129 | =cut |
1123 | |
1130 | |
1124 | sub remove { |
1131 | sub remove { |
1125 | my ($obj, $nrof) = @_; |
1132 | my ($obj, $nrof) = @_; |
1126 | |
1133 | |
1127 | my $c = $obj->nrof || 1; |
1134 | my $c = $obj->number_of; |
1128 | my $r = $c > $nrof ? 0 : $nrof - $c; |
1135 | my $r = $c > $nrof ? 0 : $nrof - $c; |
1129 | $obj->decrease (defined ($nrof) ? $nrof : ($obj->nrof || 1)); |
1136 | $obj->decrease (defined ($nrof) ? $nrof : ($obj->nrof || 1)); |
1130 | |
1137 | |
1131 | $r |
1138 | $r |
1132 | } |
1139 | } |