… | |
… | |
7 | The Jeweler skill helper module. |
7 | The Jeweler skill helper module. |
8 | |
8 | |
9 | =cut |
9 | =cut |
10 | |
10 | |
11 | package Jeweler; |
11 | package Jeweler; |
|
|
12 | |
12 | use strict; |
13 | use strict; |
13 | use YAML; |
14 | use YAML; |
14 | |
15 | |
15 | =over 4 |
16 | =over 4 |
16 | |
17 | |
… | |
… | |
34 | $CFG = YAML::LoadFile $filename; |
35 | $CFG = YAML::LoadFile $filename; |
35 | } |
36 | } |
36 | |
37 | |
37 | sub getcfg { |
38 | sub getcfg { |
38 | my ($sect, $key) = @_; |
39 | my ($sect, $key) = @_; |
|
|
40 | return $CFG->{$sect} unless defined $key; |
|
|
41 | |
39 | my $cfg = $CFG->{$sect}->{$key} |
42 | my $cfg = $CFG->{$sect}->{$key} |
40 | or die "Couldn't find $sect/$key in configuration!"; |
43 | or die "Couldn't find $sect/$key in configuration!"; |
41 | |
44 | |
42 | $cfg |
45 | $cfg |
43 | } |
|
|
44 | |
|
|
45 | # makes a template arch (for example to get the value) |
|
|
46 | sub get_arch { |
|
|
47 | my ($outarch) = @_; |
|
|
48 | unless ($CFG->{arch}->{$outarch}) { |
|
|
49 | $CFG->{arch}->{$outarch} = cf::object::new $outarch; |
|
|
50 | |
|
|
51 | unless ($CFG->{arch}->{$outarch}) { |
|
|
52 | warn "ERROR: Couldn't make $outarch in conversion for $outarch!"; |
|
|
53 | return; |
|
|
54 | } |
|
|
55 | } |
|
|
56 | $CFG->{arch}->{$outarch} |
|
|
57 | } |
46 | } |
58 | |
47 | |
59 | our @RESISTS = ( |
48 | our @RESISTS = ( |
60 | cf::ATNR_PHYSICAL, |
49 | cf::ATNR_PHYSICAL, |
61 | cf::ATNR_MAGIC, |
50 | cf::ATNR_MAGIC, |
… | |
… | |
143 | -4 => 10, |
132 | -4 => 10, |
144 | -5 => 0 |
133 | -5 => 0 |
145 | ); |
134 | ); |
146 | |
135 | |
147 | our %LVL_DIFF_MSG = ( |
136 | our %LVL_DIFF_MSG = ( |
148 | -5 => '%s is way above your skill', |
137 | -5 => 'Way above your skill', |
149 | -4 => 'The chance to make %s is very low', |
138 | -4 => 'Very low', |
150 | -3 => 'You hava a slight chance to make %s', |
139 | -3 => 'Slight chance', |
151 | -2 => 'There is a low chance you finish %s', |
140 | -2 => 'Low', |
152 | -1 => 'You could make %s with a chance of nearly 50:50', |
141 | -1 => 'Nearly 50:50', |
153 | 0 => 'The chances to fininsh %s is 50:50', |
142 | 0 => '50:50', |
154 | 1 => 'To make %s your chance is slightly above 50:50', |
143 | 1 => 'Slightly above 50:50', |
155 | 2 => 'You could make with a good chance %s if you concentrate a lot', |
144 | 2 => 'Good', |
156 | 3 => 'The chance you finish %s with some efford is high', |
145 | 3 => 'High', |
157 | 4 => 'You are nearly confident to finish %s', |
146 | 4 => 'Nearly confident', |
158 | 5 => 'There is no chance you could fail to make %s', |
147 | 5 => '100%', |
159 | ); |
148 | ); |
160 | |
149 | |
161 | sub level_diff_to_str { |
150 | sub level_diff_to_str { |
162 | my ($delta) = @_; |
151 | my ($delta) = @_; |
163 | $delta = -5 if $delta < -5; |
152 | $delta = -5 if $delta < -5; |
… | |
… | |
173 | } |
162 | } |
174 | |
163 | |
175 | sub analyze { |
164 | sub analyze { |
176 | my ($sk, $chdl, $pl) = @_; |
165 | my ($sk, $chdl, $pl) = @_; |
177 | |
166 | |
|
|
167 | my $hadunid = 0; |
178 | for ($chdl->grep_by_type (cf::RING, cf::AMULET)) { |
168 | for ($chdl->grep_by_type (cf::RING, cf::AMULET)) { |
179 | my $sklvl = cf::exp_to_level ($sk->stats->exp); |
169 | if (!$_->flag (cf::FLAG_IDENTIFIED) && $_->need_identify) { |
|
|
170 | $hadunid = 1; |
|
|
171 | next; |
|
|
172 | } |
180 | my $ringlvl = Jeweler::Object->new (object => $_)->power_to_level; |
173 | my $r = Jeweler::Object->new (object => $_); |
181 | |
174 | my $msg = $r->analyze ($sk, $pl); |
|
|
175 | $pl->message ($r->to_string . ": " . $msg); |
182 | if ($pl->get_flag (cf::FLAG_WIZ)) { |
176 | if ($pl->flag (cf::FLAG_WIZ)) { |
183 | $pl->message ("The " . $_->name . " is at level $ringlvl chance for you: " . level_diff_to_chance_perc ($sklvl - $ringlvl)); |
177 | $r->wiz_analyze ($pl); |
184 | } else { |
|
|
185 | my $tmpl = level_diff_to_str ($sklvl - $ringlvl); |
|
|
186 | my $msg = sprintf $tmpl, $_->name; |
|
|
187 | $pl->message ($msg); |
|
|
188 | } |
178 | } |
|
|
179 | } |
|
|
180 | if ($hadunid) { |
|
|
181 | $pl->message ("You couldn't identify the other rings and not analyze them!"); |
189 | } |
182 | } |
190 | } |
183 | } |
191 | |
184 | |
192 | # this function converts metals/minerals into a raw ring (of adornment) |
185 | # this function converts metals/minerals into a raw ring (of adornment) |
193 | sub simple_converter { |
186 | sub simple_converter { |
… | |
… | |
213 | warn "WARNING: xp gain isn't > 0 in convesion '$outarch'\n"; |
206 | warn "WARNING: xp gain isn't > 0 in convesion '$outarch'\n"; |
214 | return; |
207 | return; |
215 | } |
208 | } |
216 | |
209 | |
217 | unless ($outarchvalfact) { |
210 | unless ($outarchvalfact) { |
218 | warn "ERROR: source-arch-value-multiplier == 0 in convesion '$outarch'\n"; |
211 | warn "ERROR: source-arch-value-multiplier == 0 in conversion '$outarch'\n"; |
219 | return; |
212 | return; |
220 | } |
213 | } |
221 | |
214 | |
222 | unless ($outarchvalfact >= 1) { |
215 | unless ($outarchvalfact >= 1) { |
223 | warn "WARNING: source-arch-value-multiplier < 1 in convesion '$outarch', results in more valuable output!\n"; |
216 | warn "WARNING: source-arch-value-multiplier < 1 in conversion '$outarch', results in more valuable output!\n"; |
224 | } |
217 | } |
225 | |
218 | |
226 | my $archvalsum = $ingred->value ($cnvs->{$outarch}->[0], $cnvs->{$outarch}->[2]); |
219 | my $archvalsum = $ingred->value ($ingr_grp, $srcarchname); |
227 | $ingred->remove ($cnvs->{$outarch}->[0], $cnvs->{$outarch}->[2]); |
220 | $ingred->remove ($ingr_grp, $srcarchname); |
228 | |
221 | |
229 | my $outarchval = Jeweler::get_arch ($outarch)->value; |
222 | my $outarchval = cf::arch::find ($outarch)->clone->value; |
230 | |
223 | |
231 | my $nrof = int ($archvalsum / (($outarchval || 1000) * $outarchvalfact)); |
224 | my $nrof = int ($archvalsum / (($outarchval || 1000) * $outarchvalfact)); |
232 | if ($nrof) { |
225 | if ($nrof) { |
233 | # XXX: yes, i know what i'm doing here, i don't set nrof, but it didn't work somehow (pls. chek sometimes) |
226 | # XXX: yes, i know what i'm doing here, i don't set nrof, but it didn't work somehow (pls. chek sometimes) |
234 | $chdl->put (cf::object::new $outarch) for 1..$nrof; |
227 | $chdl->put (cf::object::new $outarch) for 1..$nrof; |
… | |
… | |
242 | } |
235 | } |
243 | } |
236 | } |
244 | |
237 | |
245 | |
238 | |
246 | package Jeweler::CauldronHandler; |
239 | package Jeweler::CauldronHandler; |
|
|
240 | |
247 | use strict; |
241 | use strict; |
248 | |
242 | |
249 | =head2 CauldronHandler |
243 | =head2 CauldronHandler |
250 | |
244 | |
251 | The Jeweler::CauldronHandler package, that helps you with handling the |
245 | The Jeweler::CauldronHandler package, that helps you with handling the |
… | |
… | |
277 | my ($self, $arch_name, @map_stack) = @_; |
271 | my ($self, $arch_name, @map_stack) = @_; |
278 | |
272 | |
279 | my @c = |
273 | my @c = |
280 | grep { |
274 | grep { |
281 | $_->flag (cf::FLAG_IS_CAULDRON) |
275 | $_->flag (cf::FLAG_IS_CAULDRON) |
282 | and $_->archetype->name eq $arch_name |
276 | and $_->arch->name eq $arch_name |
283 | } @map_stack; |
277 | } @map_stack; |
284 | |
278 | |
285 | $self->{cauldron} = $c[0]; |
279 | $self->{cauldron} = $c[0]; |
286 | } |
280 | } |
287 | |
281 | |
… | |
… | |
329 | |
323 | |
330 | for ($self->{cauldron}->inv) { |
324 | for ($self->{cauldron}->inv) { |
331 | |
325 | |
332 | if (my $k = $type_to_key{$_->type}) { |
326 | if (my $k = $type_to_key{$_->type}) { |
333 | push @{$ingreds->{$k}}, $_; |
327 | push @{$ingreds->{$k}}, $_; |
334 | |
|
|
335 | } else { |
|
|
336 | Jeweler::Util::remove ($_); |
|
|
337 | } |
328 | } |
338 | } |
329 | } |
339 | |
330 | |
340 | return Jeweler::Ingredients->new (ingredients => $ingreds, cauldron_helper => $self) |
331 | return Jeweler::Ingredients->new (ingredients => $ingreds, cauldron_helper => $self) |
341 | } |
332 | } |
… | |
… | |
348 | |
339 | |
349 | sub put { |
340 | sub put { |
350 | my ($self, $obj) = @_; |
341 | my ($self, $obj) = @_; |
351 | |
342 | |
352 | return undef unless $self->{cauldron}; |
343 | return undef unless $self->{cauldron}; |
353 | |
|
|
354 | $obj->insert_ob_in_ob ($self->{cauldron}); |
344 | $obj->insert_ob_in_ob ($self->{cauldron}); |
355 | } |
345 | } |
356 | |
346 | |
357 | =back |
347 | =back |
358 | |
348 | |
… | |
… | |
392 | |
382 | |
393 | sub value { |
383 | sub value { |
394 | my ($self, $group, $archname) = @_; |
384 | my ($self, $group, $archname) = @_; |
395 | |
385 | |
396 | my @objs = grep { |
386 | my @objs = grep { |
397 | $_->archetype->name eq $archname |
387 | $_->arch->name eq $archname |
398 | } @{$self->{ingredients}->{$group} || []}; |
388 | } @{$self->{ingredients}->{$group} || []}; |
399 | |
389 | |
400 | my $sum = 0; |
390 | my $sum = 0; |
401 | for (@objs) { |
391 | for (@objs) { |
402 | $sum += $_->nrof * $_->value; |
392 | $sum += ($_->nrof || 1) * $_->value; |
403 | } |
393 | } |
404 | |
394 | |
405 | return $sum; |
395 | return $sum; |
406 | } |
396 | } |
407 | |
397 | |
… | |
… | |
419 | |
409 | |
420 | my @out; |
410 | my @out; |
421 | |
411 | |
422 | for (@{$ingred->{$group}}) { |
412 | for (@{$ingred->{$group}}) { |
423 | if (defined $archname) { |
413 | if (defined $archname) { |
424 | if ($_->archetype->name eq $archname) { |
414 | if ($_->arch->name eq $archname) { |
425 | Jeweler::Util::remove ($_); |
415 | Jeweler::Util::remove ($_); |
426 | } else { |
416 | } else { |
427 | push @out, $_; |
417 | push @out, $_; |
428 | } |
418 | } |
429 | } else { |
419 | } else { |
… | |
… | |
449 | } else { |
439 | } else { |
450 | @plga = @$plg; |
440 | @plga = @$plg; |
451 | } |
441 | } |
452 | next unless @plga > 0; |
442 | next unless @plga > 0; |
453 | if (Jeweler::Util::grep_for_match ($pot, @plga)) { |
443 | if (Jeweler::Util::grep_for_match ($pot, @plga)) { |
454 | warn "MATCHED: $plan: @plga\n"; |
|
|
455 | return $plan; |
444 | return $plan; |
456 | } |
445 | } |
457 | } |
446 | } |
458 | } |
447 | } |
459 | } |
448 | } |
… | |
… | |
484 | for my $pot (@{$ingred->{potions}}) { |
473 | for my $pot (@{$ingred->{potions}}) { |
485 | if (Jeweler::Util::grep_for_match ($pot, @$plingred)) { |
474 | if (Jeweler::Util::grep_for_match ($pot, @$plingred)) { |
486 | $cnt += $pot->nrof; |
475 | $cnt += $pot->nrof; |
487 | } |
476 | } |
488 | } |
477 | } |
489 | warn "Found $cnt potions for plan $plan\n"; |
|
|
490 | |
478 | |
|
|
479 | my $maxstat = Jeweler::getcfg (maximprovements => 'stats'); |
491 | my $did_impr = 0; |
480 | my $did_impr = 0; |
492 | for my $x (reverse 1..10) { |
481 | for my $x (1..$maxstat) { |
493 | my $y = Jeweler::Object::fx ($x, 'stat_potions'); |
482 | my $y = Jeweler::Object::fx ($x, 'stat_potions'); |
494 | warn "TEST: fx($x): $y->[0] <= $cnt \n"; |
483 | |
495 | warn "FE: " . ($y->[0] == $cnt) . "\n"; |
|
|
496 | if ($cnt >= $y->[0]) { |
484 | if ($cnt <= $y->[0]) { |
497 | $ring->{hash}->{stat}->{$statname} += $x; |
485 | $ring->{hash}->{stat}->{$statname} += $x; |
498 | $did_impr = 1; |
486 | $did_impr = 1; |
499 | warn "Found stat increase of $statname +$x\n"; |
|
|
500 | last; |
487 | last; |
501 | } |
488 | } |
502 | } |
489 | } |
503 | |
490 | |
504 | # we want at least this improvement if we have a plan... |
491 | # we want at least this improvement if we have a plan... |
… | |
… | |
551 | if ($rem > 0) { |
538 | if ($rem > 0) { |
552 | warn "JEWELER BUG: removed ingredients $rem > 0 after removing!"; |
539 | warn "JEWELER BUG: removed ingredients $rem > 0 after removing!"; |
553 | } |
540 | } |
554 | } else { |
541 | } else { |
555 | my $nr; |
542 | my $nr; |
556 | $self->do_grep (sub { warn "CNT!\n"; $nr += $_[0]->nrof; 0 }, @grepar); |
543 | $self->do_grep (sub { $nr += $_[0]->nrof; 0 }, @grepar); |
557 | $costs->{$key} -= $nr; |
544 | $costs->{$key} -= $nr; |
558 | } |
545 | } |
559 | } |
546 | } |
560 | |
547 | |
561 | return $costs; |
548 | return $costs; |
… | |
… | |
588 | my $self = bless { }, $class; |
575 | my $self = bless { }, $class; |
589 | |
576 | |
590 | $self->ring_or_ammy_to_hash ($arg{object}); |
577 | $self->ring_or_ammy_to_hash ($arg{object}); |
591 | |
578 | |
592 | $self; |
579 | $self; |
|
|
580 | } |
|
|
581 | |
|
|
582 | sub analyze { |
|
|
583 | my ($self, $sk, $pl) = @_; |
|
|
584 | |
|
|
585 | my $sklvl = cf::exp_to_level ($sk->stats->exp); |
|
|
586 | my $ringlvl = $self->power_to_level; |
|
|
587 | |
|
|
588 | my $tmpl; |
|
|
589 | if ($pl->flag (cf::FLAG_WIZ)) { |
|
|
590 | $tmpl = Jeweler::level_diff_to_chance_perc ($sklvl - $ringlvl); |
|
|
591 | } else { |
|
|
592 | $tmpl = Jeweler::level_diff_to_str ($sklvl - $ringlvl); |
|
|
593 | } |
|
|
594 | my $msg = sprintf "Projected success rate: %s", $tmpl; |
|
|
595 | return $msg; |
|
|
596 | } |
|
|
597 | |
|
|
598 | sub wiz_analyze { |
|
|
599 | my ($self, $pl) = @_; |
|
|
600 | my $costs = $self->calc_costs; |
|
|
601 | my $desc = ""; |
|
|
602 | my $lvl = $self->power_to_level (\$desc); |
|
|
603 | $pl->message ("costs: " . join (', ', map { "$_: " . sprintf "%.2f", $costs->{$_} } keys %$costs)); |
|
|
604 | $pl->message ("level: " . $desc); |
|
|
605 | } |
|
|
606 | |
|
|
607 | |
|
|
608 | sub get_chance_perc { |
|
|
609 | my ($self, $sk) = @_; |
|
|
610 | my $sklvl = cf::exp_to_level ($sk->stats->exp); |
|
|
611 | my $ringlvl = $self->power_to_level; |
|
|
612 | return Jeweler::level_diff_to_chance_perc ($sklvl - $ringlvl); |
593 | } |
613 | } |
594 | |
614 | |
595 | sub fx { |
615 | sub fx { |
596 | my ($res, $cfg) = @_; |
616 | my ($res, $cfg) = @_; |
597 | my $or = $res; |
617 | my $or = $res; |
… | |
… | |
616 | } |
636 | } |
617 | } |
637 | } |
618 | } |
638 | } |
619 | } |
639 | } |
620 | |
640 | |
|
|
641 | sub negate { |
|
|
642 | my ($self) = @_; |
|
|
643 | for my $cat (qw/stat spec resist/) { |
|
|
644 | for my $k (keys %{$self->{hash}->{$cat}}) { |
|
|
645 | if ($self->{hash}->{$cat}->{$k} > 0) { |
|
|
646 | $self->{hash}->{$cat}->{$k} *= -1; |
|
|
647 | } |
|
|
648 | } |
|
|
649 | } |
|
|
650 | } |
|
|
651 | |
|
|
652 | sub to_string { |
|
|
653 | my ($self) = @_; |
|
|
654 | my $r = $self->{hash}; |
|
|
655 | return |
|
|
656 | $r->{arch} . " " . |
|
|
657 | join ("", |
|
|
658 | grep { $_ ne "" } |
|
|
659 | join ("", |
|
|
660 | (map { |
|
|
661 | my $rv = $r->{resist}->{$_}; |
|
|
662 | "(resist " . (lc $Jeweler::RESMAP{$_}) . " " . ($rv > 0 ? '+' : '') . $rv . ")" |
|
|
663 | } grep { $r->{resist}->{$_} } @Jeweler::RESISTS), |
|
|
664 | (map { |
|
|
665 | my $rv = $r->{stat}->{$_}; |
|
|
666 | "(" . (ucfirst lc $_) . ($rv > 0 ? '+' : '') . $rv . ")" |
|
|
667 | } grep { $r->{stat}->{$_} } keys %{$r->{stat}}), |
|
|
668 | (map { |
|
|
669 | my $rv = $r->{spec}->{$_}; |
|
|
670 | "(" . (lc $_) . ($rv > 0 ? '+' : '') . $rv . ")" |
|
|
671 | } grep { $r->{spec}->{$_} } keys %{$r->{spec}}))) |
|
|
672 | } |
|
|
673 | |
621 | sub ring_or_ammy_to_hash { |
674 | sub ring_or_ammy_to_hash { |
622 | my ($self, $thing) = @_; |
675 | my ($self, $thing) = @_; |
623 | |
676 | |
624 | my $obj = {}; |
677 | my $obj = {}; |
625 | |
678 | |
626 | for (@Jeweler::RESISTS) { |
679 | for (@Jeweler::RESISTS) { |
627 | $obj->{resist}->{$_} = $thing->get_resistance ($_); |
680 | $obj->{resist}->{$_} = $thing->resistance ($_); |
628 | } |
681 | } |
629 | |
682 | |
630 | my $stats = $thing->stats; |
683 | my $stats = $thing->stats; |
631 | |
684 | |
632 | for (qw/Str Dex Con Wis Cha Int Pow/) { |
685 | for (qw/Str Dex Con Wis Cha Int Pow/) { |
633 | $obj->{stat}->{lc $_} = $stats->$_; |
686 | $obj->{stat}->{lc $_} = $stats->$_; |
634 | } |
687 | } |
635 | |
688 | |
636 | $obj->{spec}->{regen} = $thing->hp; |
689 | $obj->{spec}{regen} = $stats->hp; |
637 | $obj->{spec}->{magic} = $thing->sp; |
690 | $obj->{spec}{magic} = $stats->sp; |
638 | $obj->{spec}->{wc} = $thing->wc; |
691 | $obj->{spec}{wc} = $stats->wc; |
639 | $obj->{spec}->{dam} = $thing->dam; |
692 | $obj->{spec}{dam} = $stats->dam; |
640 | $obj->{spec}->{ac} = $thing->ac; |
693 | $obj->{spec}{ac} = $stats->ac; |
641 | $obj->{spec}->{speed} = $thing->stats->exp; |
694 | $obj->{spec}{speed} = $stats->exp; |
642 | $obj->{spec}->{suste} = $thing->food; |
695 | $obj->{spec}{food} = $stats->food; |
643 | |
696 | |
644 | $obj->{name} = $thing->name; |
697 | $obj->{name} = $thing->name; |
645 | $obj->{arch} = $thing->archetype->name; |
698 | $obj->{arch} = $thing->arch->name; |
646 | $obj->{face} = $thing->face; |
699 | $obj->{face} = $thing->face; |
647 | |
700 | |
648 | $self->{hash} = $obj |
701 | $self->{hash} = $obj |
649 | } |
702 | } |
650 | |
703 | |
651 | sub to_object { |
704 | sub to_object { |
652 | my ($self) = @_; |
705 | my ($self) = @_; |
|
|
706 | |
653 | my $obj = cf::object::new $self->{hash}->{arch}; |
707 | my $obj = cf::object::new $self->{hash}->{arch}; |
|
|
708 | |
654 | $obj->set_face ($self->{hash}->{face}); |
709 | $obj->face ($self->{hash}{face}); |
655 | |
710 | |
|
|
711 | my $stats = $obj->stats; |
|
|
712 | |
656 | $obj->set_hp ($self->{hash}->{spec}->{regen} * 1); |
713 | $stats->hp ($self->{hash}{spec}{regen}); |
657 | $obj->set_sp ($self->{hash}->{spec}->{magic} * 1); |
714 | $stats->sp ($self->{hash}{spec}{magic}); |
658 | $obj->set_wc ($self->{hash}->{spec}->{wc} * 1); |
715 | $stats->wc ($self->{hash}{spec}{wc}); |
659 | $obj->set_dam ($self->{hash}->{spec}->{dam} * 1); |
716 | $stats->dam ($self->{hash}{spec}{dam}); |
660 | $obj->set_ac ($self->{hash}->{spec}->{ac} * 1); |
717 | $stats->ac ($self->{hash}{spec}{ac}); |
661 | $obj->stats->exp ($self->{hash}->{spec}->{speed} * 1); |
718 | $stats->exp ($self->{hash}{spec}{speed}); |
662 | $obj->set_food ($self->{hash}->{spec}->{suste} * 1); |
719 | $stats->food ($self->{hash}{spec}{food}); |
663 | |
720 | |
|
|
721 | $stats->$_ ($self->{hash}{stat}{lc $_}) |
664 | for (qw/Str Dex Con Wis Cha Int Pow/) { |
722 | for qw/Str Dex Con Wis Cha Int Pow/; |
665 | $obj->stats->$_ ($self->{hash}->{stat}->{lc $_} * 1); |
|
|
666 | } |
|
|
667 | |
723 | |
668 | for (@Jeweler::RESISTS) { |
724 | for (@Jeweler::RESISTS) { |
669 | $obj->set_resistance ($_, $self->{hash}->{resist}->{$_} * 1); |
725 | $obj->resistance ($_, $self->{hash}->{resist}->{$_}); |
670 | } |
726 | } |
671 | |
727 | |
672 | $obj->set_flag (cf::FLAG_IDENTIFIED, 1); |
728 | $obj->flag (cf::FLAG_IDENTIFIED, 1); |
673 | |
729 | |
674 | return $obj; |
730 | return $obj; |
675 | } |
731 | } |
676 | |
732 | |
677 | sub stat_level { |
733 | sub stat_level { |
… | |
… | |
680 | |
736 | |
681 | my $maxlevel = Jeweler::getcfg (maxlevels => 'stat_level'); |
737 | my $maxlevel = Jeweler::getcfg (maxlevels => 'stat_level'); |
682 | my $maxstat = Jeweler::getcfg (maximprovements => 'stats'); |
738 | my $maxstat = Jeweler::getcfg (maximprovements => 'stats'); |
683 | |
739 | |
684 | my $stat_cnt = scalar (grep { $_ > 0 } values %$stats); |
740 | my $stat_cnt = scalar (grep { $_ > 0 } values %$stats); |
685 | my $stat_sum = sum (values %$stats); |
741 | my $stat_sum = sum (values %$stats); # also count the negative stats! |
686 | my $level = int (($maxlevel / $maxstat) * $stat_sum); |
742 | my $level = int (($maxlevel / $maxstat) * $stat_sum); |
687 | |
743 | |
688 | ($level, $stat_cnt) |
744 | ($level, $stat_cnt) |
689 | } |
745 | } |
690 | |
746 | |
… | |
… | |
758 | } |
814 | } |
759 | |
815 | |
760 | |
816 | |
761 | # this function calculated the 'level' of an amulet or a ring |
817 | # this function calculated the 'level' of an amulet or a ring |
762 | sub power_to_level { |
818 | sub power_to_level { |
763 | my ($self) = @_; |
819 | my ($self, $lvldescr) = @_; |
764 | |
820 | |
765 | my $max_imprs = Jeweler::getcfg (maximprovements => 'improvements'); |
821 | my $max_imprs = Jeweler::getcfg (maximprovements => 'improvements'); |
766 | my $max_impr_lvl = Jeweler::getcfg (maxlevels => 'improve_level'); |
822 | my $max_impr_lvl = Jeweler::getcfg (maxlevels => 'improve_level'); |
767 | |
823 | |
768 | my ($stat_lvl, $stat_imprs) = $self->stat_level; |
824 | my ($stat_lvl, $stat_imprs) = $self->stat_level; |
… | |
… | |
773 | |
829 | |
774 | my $impr_lvl = ceil (($max_impr_lvl / ($max_imprs + 1)) * ($impr_sum - 1)); # 1 improvemnt bonus |
830 | my $impr_lvl = ceil (($max_impr_lvl / ($max_imprs + 1)) * ($impr_sum - 1)); # 1 improvemnt bonus |
775 | |
831 | |
776 | my $levl = int max ($stat_lvl, $resist_lvl, $impr_lvl, $spec_lvl, 0); |
832 | my $levl = int max ($stat_lvl, $resist_lvl, $impr_lvl, $spec_lvl, 0); |
777 | |
833 | |
778 | my $cost = $self->calc_costs; |
834 | if ($lvldescr) { |
779 | warn |
835 | $$lvldescr = |
780 | sprintf "%3d: %50s: %s\n", $levl, $self->{hash}->{name}, |
836 | sprintf "%3d: %s\n", $levl, |
781 | "stat: $stat_lvl, resist: $resist_lvl, improve: $impr_lvl, " |
837 | "stat: $stat_lvl, resist: $resist_lvl, improve: $impr_lvl, " |
782 | ."spec: $spec_lvl (num impr $stat_imprs + $res_imprs + $spec_imprs - 1)"; |
838 | ."spec: $spec_lvl (num impr $stat_imprs + $res_imprs + $spec_imprs - 1)"; |
|
|
839 | } |
783 | |
840 | |
784 | $levl |
841 | $levl |
785 | } |
842 | } |
786 | |
843 | |
787 | sub add_stat_costs { |
844 | sub add_stat_costs { |
… | |
… | |
842 | } |
899 | } |
843 | |
900 | |
844 | $self->add_stat_costs ($costs); |
901 | $self->add_stat_costs ($costs); |
845 | $self->add_special_costs ($costs); |
902 | $self->add_special_costs ($costs); |
846 | |
903 | |
847 | warn |
|
|
848 | sprintf "JEWEL ANALYSE: %40s: %s" , |
|
|
849 | $ring->{name}, |
|
|
850 | join (', ', map { "$_: " . sprintf "%.2f", $costs->{$_} } keys %$costs); |
|
|
851 | |
|
|
852 | return $costs; |
904 | return $costs; |
853 | } |
905 | } |
854 | |
906 | |
855 | sub split_diamonds { |
907 | sub split_diamonds { |
856 | my ($cost, $diamonds, $category) = @_; |
908 | my ($cost, $diamonds, $category) = @_; |
… | |
… | |
860 | my $sum = sum (@$stat_split); |
912 | my $sum = sum (@$stat_split); |
861 | if ($sum < (1 - 0.0001)) { |
913 | if ($sum < (1 - 0.0001)) { |
862 | warn "JEWELER BUG: sum (@$stat_split) = $sum < 1 for $category!"; |
914 | warn "JEWELER BUG: sum (@$stat_split) = $sum < 1 for $category!"; |
863 | } |
915 | } |
864 | |
916 | |
865 | my $emarch = Jeweler::get_arch ('emerald'); |
917 | my $emarch = cf::arch::find 'emerald'; |
866 | my $saarch = Jeweler::get_arch ('sapphire'); |
918 | my $saarch = cf::arch::find 'sapphire'; |
867 | my $pearch = Jeweler::get_arch ('pearl'); |
919 | my $pearch = cf::arch::find 'pearl'; |
868 | my $ruarch = Jeweler::get_arch ('ruby'); |
920 | my $ruarch = cf::arch::find 'ruby'; |
869 | my $diarch = Jeweler::get_arch ('gem'); |
921 | my $diarch = cf::arch::find 'gem'; |
870 | |
922 | |
871 | my $sumvalue = $diarch->value * $diamonds; |
923 | my $sumvalue = $diarch->clone->value * $diamonds; |
872 | |
924 | |
873 | $cost->{emerald} += ceil (($sumvalue * $stat_split->[0]) / max (1, $emarch->value)); |
925 | $cost->{emerald} += ceil $sumvalue * $stat_split->[0] / max 1, $emarch->clone->value; |
874 | $cost->{sapphire} += ceil (($sumvalue * $stat_split->[1]) / max (1, $saarch->value)); |
926 | $cost->{sapphire} += ceil $sumvalue * $stat_split->[1] / max 1, $saarch->clone->value; |
875 | $cost->{pearl} += ceil (($sumvalue * $stat_split->[2]) / max (1, $pearch->value)); |
927 | $cost->{pearl} += ceil $sumvalue * $stat_split->[2] / max 1, $pearch->clone->value; |
876 | $cost->{ruby} += ceil (($sumvalue * $stat_split->[3]) / max (1, $ruarch->value)); |
928 | $cost->{ruby} += ceil $sumvalue * $stat_split->[3] / max 1, $ruarch->clone->value; |
877 | $cost->{gem} += ceil (($sumvalue * $stat_split->[4]) / max (1, $diarch->value)); |
929 | $cost->{gem} += ceil $sumvalue * $stat_split->[4] / max 1, $diarch->clone->value; |
878 | } |
930 | } |
879 | |
|
|
880 | |
|
|
881 | |
931 | |
882 | package Jeweler::Util; |
932 | package Jeweler::Util; |
|
|
933 | |
883 | use strict; |
934 | use strict; |
884 | |
935 | |
885 | =head2 Util |
936 | =head2 Util |
886 | |
937 | |
887 | Some utility functions for the Jeweler skill. |
938 | Some utility functions for the Jeweler skill. |
… | |
… | |
896 | =cut |
947 | =cut |
897 | |
948 | |
898 | sub remove { |
949 | sub remove { |
899 | my ($obj, $nrof) = @_; |
950 | my ($obj, $nrof) = @_; |
900 | |
951 | |
901 | #XXX: waht about this: remove ($_) for ($obj->inv) ? |
952 | my $cnt; |
902 | |
953 | |
|
|
954 | if (defined $nrof) { |
|
|
955 | return 0 if ($nrof * 1) == 0; |
903 | my $cnt = $obj->nrof - (1 * $nrof); |
956 | $cnt = int (($obj->nrof || 1) - (1 * $nrof)); |
904 | |
957 | |
905 | if ($cnt > 0) { |
958 | if ($cnt > 0) { |
906 | $obj->set_nrof ($cnt); |
959 | $obj->nrof ($cnt); |
907 | return 0; |
960 | return 0; |
908 | } else { |
961 | } |
909 | $obj->remove; |
962 | } |
910 | $obj->free; |
963 | |
|
|
964 | remove ($_) for $obj->inv; |
|
|
965 | $obj->destroy; |
911 | return $cnt; |
966 | return $cnt; |
912 | } |
|
|
913 | } |
967 | } |
914 | |
968 | |
915 | sub grep_for_match { |
969 | sub grep_for_match { |
916 | my ($thing, @matchar) = @_; |
970 | my ($thing, @matchar) = @_; |
917 | |
971 | |
… | |
… | |
927 | and return 1; |
981 | and return 1; |
928 | } elsif ($i % 3 == 1) { |
982 | } elsif ($i % 3 == 1) { |
929 | $thing->title eq $match |
983 | $thing->title eq $match |
930 | and return 1; |
984 | and return 1; |
931 | } else { # $i % 3 == 2 |
985 | } else { # $i % 3 == 2 |
932 | $thing->archetype->name eq $match |
986 | $thing->arch->name eq $match |
933 | and return 1; |
987 | and return 1; |
934 | } |
988 | } |
935 | $i++; |
989 | $i++; |
936 | } |
990 | } |
937 | return 0; |
991 | return 0; |