ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/maps/perl/Jeweler.pm
(Generate patch)

Comparing deliantra/maps/perl/Jeweler.pm (file contents):
Revision 1.1 by elmex, Sat Jul 15 12:57:41 2006 UTC vs.
Revision 1.2 by elmex, Thu Aug 31 00:58:17 2006 UTC

7The Jeweler skill helper module. 7The Jeweler skill helper module.
8 8
9=cut 9=cut
10 10
11package Jeweler; 11package Jeweler;
12use strict;
13use YAML;
12 14
13=over 4 15=over 4
14 16
15=item @RESISTS 17=item @RESISTS
16 18
17List of all resistancies that can occur on rings and amulets. 19List of all resistancies that can occur on rings and amulets.
18 20
19=cut 21=cut
20 22
23our $CFG;
24
25sub read_config {
26 my ($filename) = @_;
27
28 unless (-e $filename) {
29 warn "$filename doesn't exists! no config for jeweler skill loaded!\n";
30 $CFG = {};
31 return
32 }
33
34 $CFG = YAML::LoadFile $filename;
35}
36
37sub getcfg {
38 my ($sect, $key) = @_;
39 my $cfg = $CFG->{$sect}->{$key}
40 or die "Couldn't find $sect/$key in configuration!";
41
42 $cfg
43}
44
45# makes a template arch (for example to get the value)
46sub 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}
58
21my @RESISTS = ( 59our @RESISTS = (
22 cf::ATNR_PHYSICAL, 60 cf::ATNR_PHYSICAL,
23 cf::ATNR_MAGIC, 61 cf::ATNR_MAGIC,
24 cf::ATNR_FIRE, 62 cf::ATNR_FIRE,
25 cf::ATNR_ELECTRICITY, 63 cf::ATNR_ELECTRICITY,
26 cf::ATNR_COLD, 64 cf::ATNR_COLD,
47=item @EFFECT_RESISTS 85=item @EFFECT_RESISTS
48 86
49List of all effect resistancies that occur on rings and amulets. 87List of all effect resistancies that occur on rings and amulets.
50The difference is made because effect resistancies are less effective at lower levels. 88The difference is made because effect resistancies are less effective at lower levels.
51 89
52=cut 90=back
53 91
92=cut
93
54my @EFFECT_RESISTS = ( 94our @EFFECT_RESISTS = (
55 cf::ATNR_CONFUSION, 95 cf::ATNR_CONFUSION,
56 cf::ATNR_DRAIN, 96 cf::ATNR_DRAIN,
57 cf::ATNR_POISON, 97 cf::ATNR_POISON,
58 cf::ATNR_SLOW, 98 cf::ATNR_SLOW,
59 cf::ATNR_PARALYZE, 99 cf::ATNR_PARALYZE,
63 cf::ATNR_DEATH, 103 cf::ATNR_DEATH,
64 cf::ATNR_BLIND, 104 cf::ATNR_BLIND,
65 cf::ATNR_DISEASE, 105 cf::ATNR_DISEASE,
66); 106);
67 107
68my %RESMAP = ( 108our %RESMAP = (
69 cf::ATNR_PHYSICAL => "PHYSICAL", 109 cf::ATNR_PHYSICAL => "PHYSICAL",
70 cf::ATNR_MAGIC => "MAGIC", 110 cf::ATNR_MAGIC => "MAGIC",
71 cf::ATNR_FIRE => "FIRE", 111 cf::ATNR_FIRE => "FIRE",
72 cf::ATNR_ELECTRICITY => "ELECTRICITY", 112 cf::ATNR_ELECTRICITY => "ELECTRICITY",
73 cf::ATNR_COLD => "COLD", 113 cf::ATNR_COLD => "COLD",
88 cf::ATNR_LIFE_STEALING => "LIFE_STEALING", 128 cf::ATNR_LIFE_STEALING => "LIFE_STEALING",
89 cf::ATNR_BLIND => "BLIND", 129 cf::ATNR_BLIND => "BLIND",
90 cf::ATNR_DISEASE => "DISEASE", 130 cf::ATNR_DISEASE => "DISEASE",
91); 131);
92 132
93=back 133our %LVL_DIFF_CHANCES = (
134 +5 => 100,
135 +4 => 95,
136 +3 => 85,
137 +2 => 75,
138 +1 => 65,
139 0 => 50,
140 -1 => 45,
141 -2 => 35,
142 -3 => 25,
143 -4 => 10,
144 -5 => 0
145);
94 146
95=cut 147our %LVL_DIFF_MSG = (
148 -5 => '%s is way above your skill',
149 -4 => 'The chance to make %s is very low',
150 -3 => 'You hava a slight chance to make %s',
151 -2 => 'There is a low chance you finish %s',
152 -1 => 'You could make %s with a chance of nearly 50:50',
153 0 => 'The chances to fininsh %s is 50:50',
154 1 => 'To make %s your chance is slightly above 50:50',
155 2 => 'You could make with a good chance %s if you concentrate a lot',
156 3 => 'The chance you finish %s with some efford is high',
157 4 => 'You are nearly confident to finish %s',
158 5 => 'There is no chance you could fail to make %s',
159);
160
161sub level_diff_to_str {
162 my ($delta) = @_;
163 $delta = -5 if $delta < -5;
164 $delta = 5 if $delta > 5;
165 return $LVL_DIFF_MSG{$delta}
166}
167
168sub level_diff_to_chance_perc {
169 my ($delta) = @_;
170 $delta = -5 if $delta < -5;
171 $delta = 5 if $delta > 5;
172 return $LVL_DIFF_CHANCES{$delta}
173}
174
175sub analyze {
176 my ($sk, $chdl, $pl) = @_;
177
178 for ($chdl->grep_by_type (cf::RING, cf::AMULET)) {
179 my $sklvl = cf::exp_to_level ($sk->stats->exp);
180 my $ringlvl = Jeweler::Object->new (object => $_)->power_to_level;
181
182 if ($pl->get_flag (cf::FLAG_WIZ)) {
183 $pl->message ("The " . $_->name . " is at level $ringlvl chance for you: " . level_diff_to_chance_perc ($sklvl - $ringlvl));
184 } else {
185 my $tmpl = level_diff_to_str ($sklvl - $ringlvl);
186 my $msg = sprintf $tmpl, $_->name;
187 $pl->message ($msg);
188 }
189 }
190}
191
192# this function converts metals/minerals into a raw ring (of adornment)
193sub simple_converter {
194 my ($pl, $ingred, $chdl, $conv) = @_;
195
196 $conv = lc $conv;
197 my $cnvs = $CFG->{conversions};
198
199 return unless $cnvs->{$conv};
200
201 my %ingred_groups;
202
203 my @conv_cfg = @{$cnvs->{$conv}};
204 my $outarch = $conv;
205 my ($ingr_grp, $outarchvalfact, $srcarchname, $xp_gain) = @conv_cfg;
206
207 unless (@conv_cfg <= 4) {
208 warn "ERROR: Conversion for '$outarch' has only " . (@conv_cfg) . " arguments!";
209 return;
210 }
211
212 unless ($xp_gain > 0) {
213 warn "WARNING: xp gain isn't > 0 in convesion '$outarch'\n";
214 return;
215 }
216
217 unless ($outarchvalfact) {
218 warn "ERROR: source-arch-value-multiplier == 0 in convesion '$outarch'\n";
219 return;
220 }
221
222 unless ($outarchvalfact >= 1) {
223 warn "WARNING: source-arch-value-multiplier < 1 in convesion '$outarch', results in more valuable output!\n";
224 }
225
226 my $archvalsum = $ingred->value ($cnvs->{$outarch}->[0], $cnvs->{$outarch}->[2]);
227 $ingred->remove ($cnvs->{$outarch}->[0], $cnvs->{$outarch}->[2]);
228
229 my $outarchval = Jeweler::get_arch ($outarch)->value;
230
231 my $nrof = int ($archvalsum / (($outarchval || 1000) * $outarchvalfact));
232 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)
234 $chdl->put (cf::object::new $outarch) for 1..$nrof;
235
236 my $xp_sum = ($xp_gain * $nrof);
237
238 if ($xp_sum) {
239 $pl->ob->message ("You got $xp_sum xp by making $nrof ${outarch}s");
240 $pl->ob->change_exp ($xp_sum, "jeweler", cf::SK_EXP_ADD_SKILL);
241 }
242 }
243}
244
96 245
97package Jeweler::CauldronHandler; 246package Jeweler::CauldronHandler;
247use strict;
98 248
99=head2 CauldronHandler 249=head2 CauldronHandler
100 250
101The Jeweler::CauldronHandler package, that helps you with handling the 251The Jeweler::CauldronHandler package, that helps you with handling the
102cauldron stuff. Can also be used for other skills. 252cauldron stuff. Can also be used for other skills.
207=back 357=back
208 358
209=cut 359=cut
210 360
211package Jeweler::Ingredients; 361package Jeweler::Ingredients;
362use Storable qw/dclone/;
363use strict;
212 364
213=head2 Ingredients 365=head2 Ingredients
214 366
215This class handles the ingredients. 367This class handles the ingredients.
216 368
254} 406}
255 407
256=item remove ($group, $archname) 408=item remove ($group, $archname)
257 409
258Removes the ingredients in C<$group> with archname C<$archname>. 410Removes the ingredients in C<$group> with archname C<$archname>.
411It removes all in C<$group> if archname is undef.
259 412
260=cut 413=cut
261 414
262sub remove { 415sub remove {
263 my ($self, $group, $archname) = @_; 416 my ($self, $group, $archname) = @_;
265 my $ingred = $self->{ingredients}; 418 my $ingred = $self->{ingredients};
266 419
267 my @out; 420 my @out;
268 421
269 for (@{$ingred->{$group}}) { 422 for (@{$ingred->{$group}}) {
423 if (defined $archname) {
270 if ($_->archetype->name eq $archname) { 424 if ($_->archetype->name eq $archname) {
425 Jeweler::Util::remove ($_);
426 } else {
427 push @out, $_;
428 }
429 } else {
271 Jeweler::Util::remove ($_); 430 Jeweler::Util::remove ($_);
431 }
432 }
433
434 @{$ingred->{$group}} = @out;
435}
436
437sub get_plan {
438 my ($self) = @_;
439
440 my $ingred = $self->{ingredients};
441
442 for my $grp (keys %$ingred) {
443 for my $pot (@{$ingred->{$grp}}) {
444 for my $plan (keys %{$Jeweler::CFG->{plans}}) {
445 my $plg = $Jeweler::CFG->{plans}->{$plan};
446 my @plga = ();
447 unless (ref $plg eq 'ARRAY') {
448 push @plga, $plg;
449 } else {
450 @plga = @$plg;
451 }
452 next unless @plga > 0;
453 if (Jeweler::Util::grep_for_match ($pot, @plga)) {
454 warn "MATCHED: $plan: @plga\n";
455 return $plan;
456 }
457 }
458 }
459 }
460}
461
462sub get_ring {
463 my ($self) = @_;
464 return (
465 @{$self->{ingredients}->{ammys} || []},
466 @{$self->{ingredients}->{rings} || []}
467 );
468}
469
470sub improve_ring_by_plan {
471 my ($self, $plan, $ring) = @_;
472
473 $ring = dclone ($ring);
474
475 my $ingred = $self->{ingredients};
476 my $impr = {};
477
478 if ($plan =~ m/^stat_(\S+)$/) {
479 my $statname = $1;
480 my $plingred = Jeweler::getcfg (plans => $plan)
481 or die "ingredients for plan '$plan' not defined!";
482
483 my $cnt = 0;
484 for my $pot (@{$ingred->{potions}}) {
485 if (Jeweler::Util::grep_for_match ($pot, @$plingred)) {
486 $cnt += $pot->nrof;
487 }
488 }
489 warn "Found $cnt potions for plan $plan\n";
490
491 my $did_impr = 0;
492 for my $x (reverse 1..10) {
493 my $y = Jeweler::Object::fx ($x, 'stat_potions');
494 warn "TEST: fx($x): $y->[0] <= $cnt \n";
495 warn "FE: " . ($y->[0] == $cnt) . "\n";
496 if ($cnt >= $y->[0]) {
497 $ring->{hash}->{stat}->{$statname} += $x;
498 $did_impr = 1;
499 warn "Found stat increase of $statname +$x\n";
500 last;
501 }
502 }
503
504 # we want at least this improvement if we have a plan...
505 $ring->{hash}->{stat}->{$statname} += 1 unless $did_impr;
506
507 } elsif ($plan =~ m/^spec_(\S+)$/) {
508 } elsif ($plan =~ m/^resist_(\S+)$/) {
509 }
510
511 return $ring;
512}
513
514sub do_grep {
515 my ($self, $cb, @grepar) = @_;
516
517 my $ingred = $self->{ingredients};
518
519
520 for my $cat (keys %$ingred) {
521 my @rem;
522 for my $ing (@{$ingred->{$cat}}) {
523 if (Jeweler::Util::grep_for_match ($ing, @grepar)) {
524 unless ($cb->($ing)) {
525 push @rem, $ing;
526 }
527 } else {
528 push @rem, $ing;
529 }
530 }
531 @{$ingred->{$cat}} = @rem;
532 }
533}
534
535sub check_costs {
536 my ($self, $costs, $do_remove) = @_;
537
538 my $costs = dclone ($costs);
539
540 for my $key (keys %$costs) {
541 my @grepar;
542 if ($key =~ m/^stat_(\S+)$/) {
543 @grepar = @{Jeweler::getcfg (plans => $key) || []};
272 } else { 544 } else {
273 push @out, $_; 545 @grepar = (undef, undef, $key);
546 }
547
548 if ($do_remove) {
549 my $rem = $costs->{$key};
550 $self->do_grep (sub { if ($rem) { $rem = Jeweler::Util::remove ($_[0], $rem); } 1 }, @grepar);
551 if ($rem > 0) {
552 warn "JEWELER BUG: removed ingredients $rem > 0 after removing!";
274 } 553 }
554 } else {
555 my $nr;
556 $self->do_grep (sub { warn "CNT!\n"; $nr += $_[0]->nrof; 0 }, @grepar);
557 $costs->{$key} -= $nr;
558 }
275 } 559 }
276 560
277 @{$ingred->{$grp}} = @out; 561 return $costs;
278} 562}
279 563
280=back 564=back
281 565
282=cut 566=cut
283 567
568sub put_to_bench {
569 my ($self, $bench) = @_;
570
571 my $ingred = $self->{ingredients};
572
573 for my $ik (keys %$ingred) {
574 for (@{$ingred->{$ik} || []}) {
575 $bench->put ($_);
576 }
577 }
578}
579
580package Jeweler::Object;
581use strict;
582use POSIX;
583use List::Util qw/max min sum/;
584
585sub new {
586 my ($class, %arg) = @_;
587
588 my $self = bless { }, $class;
589
590 $self->ring_or_ammy_to_hash ($arg{object});
591
592 $self;
593}
594
595sub fx {
596 my ($res, $cfg) = @_;
597 my $or = $res;
598 my $ar = $Jeweler::CFG->{functions}->{$cfg};
599 if (ref $ar->[0] eq 'ARRAY') {
600 $res = $res - 1;
601 } else {
602 $res = ceil ($res / 5) - 1;
603 }
604 $ar->[max (min ($res, @$ar - 1), 0)];
605}
606
607sub improve_by_ring {
608 my ($self, @rings) = @_;
609 my $ring = $self;
610 for my $iring (@rings) {
611 for my $cat (qw/stat spec resist/) {
612 for my $k (keys %{$iring->{hash}->{$cat}}) {
613 if ($ring->{hash}->{$cat}->{$k} < $iring->{hash}->{$cat}->{$k}) {
614 $ring->{hash}->{$cat}->{$k} = $iring->{hash}->{$cat}->{$k};
615 }
616 }
617 }
618 }
619}
620
621sub ring_or_ammy_to_hash {
622 my ($self, $thing) = @_;
623
624 my $obj = {};
625
626 for (@Jeweler::RESISTS) {
627 $obj->{resist}->{$_} = $thing->get_resistance ($_);
628 }
629
630 my $stats = $thing->stats;
631
632 for (qw/Str Dex Con Wis Cha Int Pow/) {
633 $obj->{stat}->{lc $_} = $stats->$_;
634 }
635
636 $obj->{spec}->{regen} = $thing->hp;
637 $obj->{spec}->{magic} = $thing->sp;
638 $obj->{spec}->{wc} = $thing->wc;
639 $obj->{spec}->{dam} = $thing->dam;
640 $obj->{spec}->{ac} = $thing->ac;
641 $obj->{spec}->{speed} = $thing->stats->exp;
642 $obj->{spec}->{suste} = $thing->food;
643
644 $obj->{name} = $thing->name;
645 $obj->{arch} = $thing->archetype->name;
646 $obj->{face} = $thing->face;
647
648 $self->{hash} = $obj
649}
650
651sub to_object {
652 my ($self) = @_;
653 my $obj = cf::object::new $self->{hash}->{arch};
654 $obj->set_face ($self->{hash}->{face});
655
656 $obj->set_hp ($self->{hash}->{spec}->{regen} * 1);
657 $obj->set_sp ($self->{hash}->{spec}->{magic} * 1);
658 $obj->set_wc ($self->{hash}->{spec}->{wc} * 1);
659 $obj->set_dam ($self->{hash}->{spec}->{dam} * 1);
660 $obj->set_ac ($self->{hash}->{spec}->{ac} * 1);
661 $obj->stats->exp ($self->{hash}->{spec}->{speed} * 1);
662 $obj->set_food ($self->{hash}->{spec}->{suste} * 1);
663
664 for (qw/Str Dex Con Wis Cha Int Pow/) {
665 $obj->stats->$_ ($self->{hash}->{stat}->{lc $_} * 1);
666 }
667
668 for (@Jeweler::RESISTS) {
669 $obj->set_resistance ($_, $self->{hash}->{resist}->{$_} * 1);
670 }
671
672 $obj->set_flag (cf::FLAG_IDENTIFIED, 1);
673
674 return $obj;
675}
676
677sub stat_level {
678 my ($self) = @_;
679 my $stats = $self->{hash}->{stat} || {};
680
681 my $maxlevel = Jeweler::getcfg (maxlevels => 'stat_level');
682 my $maxstat = Jeweler::getcfg (maximprovements => 'stats');
683
684 my $stat_cnt = scalar (grep { $_ > 0 } values %$stats);
685 my $stat_sum = sum (values %$stats);
686 my $level = int (($maxlevel / $maxstat) * $stat_sum);
687
688 ($level, $stat_cnt)
689}
690
691sub resist_level {
692 my ($self) = @_;
693
694 my $resists = $self->{hash}->{resist} || {};
695
696 my $att_res_lvl = Jeweler::getcfg (maxlevels => 'resist_level');
697 my $efc_res_lvl = Jeweler::getcfg (maxlevels => 'effect_resist_level');
698 my $max_att_res = Jeweler::getcfg (maximprovements => 'attack_resistances');
699 my $max_efc_res = Jeweler::getcfg (maximprovements => 'effect_resistances');
700 my $max_ovr_res = Jeweler::getcfg (maximprovements => 'resistances');
701
702 my $ressum = 0;
703 my $rescnt = 0;
704 my @reslevels;
705
706 for my $resnam (keys %$resists) {
707 my $res = $resists->{$resnam};
708
709 $rescnt++
710 if $res > 0; # negative resistancies are not an improvement
711
712 $ressum += $res; # note: negative resistancies lower the sum
713
714 next unless $res > 0;
715
716 my $level = 0;
717 if (grep { $resnam eq $_ } @Jeweler::EFFECT_RESISTS) {
718 $level = ceil (($efc_res_lvl / $max_efc_res) * $res);
719 } else {
720 $level = ceil (($att_res_lvl / $max_att_res) * $res);
721 }
722 push @reslevels, $level;
723 }
724
725 my $overall_lvl = ($att_res_lvl / $max_ovr_res) * $ressum;
726
727 (max (@reslevels, $overall_lvl), $rescnt);
728}
729
730sub special_level {
731 my ($self) = @_;
732
733 my $specials = $self->{hash}->{spec} || {};
734
735 my $max_spc_lvl = Jeweler::getcfg (maxlevels => 'spec_level');
736 my $max_specials = Jeweler::getcfg (maximprovements => 'specials');
737
738 my @speclvls;
739 my $specsum = 0;
740 my $imprs = 0;
741
742 for my $spcnam (keys %$specials) {
743 my $spc = $specials->{$spcnam};
744 next unless $spc > 0;
745
746 $specsum += $spc;
747 $imprs++;
748
749 my $max_spc = Jeweler::getcfg (maxspecial => $spcnam);
750
751 my $lvl = ($max_spc_lvl / $max_spc) * $spc;
752 push @speclvls, $lvl;
753 }
754
755 my $sumlvl = ($max_spc_lvl / $max_specials) * $specsum;
756
757 (max (@speclvls, $sumlvl), $imprs)
758}
759
760
761# this function calculated the 'level' of an amulet or a ring
762sub power_to_level {
763 my ($self) = @_;
764
765 my $max_imprs = Jeweler::getcfg (maximprovements => 'improvements');
766 my $max_impr_lvl = Jeweler::getcfg (maxlevels => 'improve_level');
767
768 my ($stat_lvl, $stat_imprs) = $self->stat_level;
769 my ($resist_lvl, $res_imprs) = $self->resist_level;
770 my ($spec_lvl, $spec_imprs) = $self->special_level;
771
772 my $impr_sum = $stat_imprs + $res_imprs + $spec_imprs;
773
774 my $impr_lvl = ceil (($max_impr_lvl / ($max_imprs + 1)) * ($impr_sum - 1)); # 1 improvemnt bonus
775
776 my $levl = int max ($stat_lvl, $resist_lvl, $impr_lvl, $spec_lvl, 0);
777
778 my $cost = $self->calc_costs;
779 warn
780 sprintf "%3d: %50s: %s\n", $levl, $self->{hash}->{name},
781 "stat: $stat_lvl, resist: $resist_lvl, improve: $impr_lvl, "
782 ."spec: $spec_lvl (num impr $stat_imprs + $res_imprs + $spec_imprs - 1)";
783
784 $levl
785}
786
787sub add_stat_costs {
788 my ($self, $cost) = @_;
789
790 my $stats = $self->{hash}->{stat};
791
792 for my $stat (keys %$stats) {
793 my $sum = $stats->{$stat};
794
795 next unless $sum > 0;
796
797 my $statfx = fx ($sum, 'stat_potions');
798 $cost->{"stat_$stat"} += $statfx->[0];
799 split_diamonds ($cost, $statfx->[1], 'stat_' . $stat);
800 }
801}
802
803sub add_special_costs {
804 my ($self, $cost) = @_;
805
806 my $specials = $self->{hash}->{spec};
807
808 for my $spec (keys %$specials) {
809 my $sum = $specials->{$spec};
810
811 next unless $sum > 0;
812
813 my $specfx = fx ($sum, 'spec_potions');
814 $cost->{"spec_$spec"} += $specfx->[0];
815 split_diamonds ($cost, $specfx->[1], 'spec_' . $spec);
816 }
817}
818
819sub calc_costs {
820 my ($self) = @_;
821
822 my $costs = {};
823
824 my $ring = $self->{hash};
825
826 for my $resnam (keys %{$ring->{resist} || {}}) {
827
828 my $res = $ring->{resist}->{$resnam};
829
830 next unless $res > 0;
831
832 $costs->{"resist_" . $Jeweler::RESMAP{$resnam} . "_item"} += $res;
833
834 my $diamonds;
835 if (grep { $resnam eq $_ } @Jeweler::EFFECT_RESISTS) {
836 $diamonds += fx ($res, 'effect_resist_diamonds');
837 } else {
838 $diamonds += fx ($res, 'attack_resist_diamonds');
839 }
840
841 split_diamonds ($costs, $diamonds, 'resist_' . $Jeweler::RESMAP{$resnam});
842 }
843
844 $self->add_stat_costs ($costs);
845 $self->add_special_costs ($costs);
846
847 warn
848 sprintf "JEWEL ANALYSE: %40s: %s" ,
849 $ring->{name},
850 join (', ', map { "$_: " . sprintf "%.2f", $costs->{$_} } keys %$costs);
851
852 return $costs;
853}
854
855sub split_diamonds {
856 my ($cost, $diamonds, $category) = @_;
857
858 my $stat_split = Jeweler::getcfg (diamond_split => $category);
859
860 my $sum = sum (@$stat_split);
861 if ($sum < (1 - 0.0001)) {
862 warn "JEWELER BUG: sum (@$stat_split) = $sum < 1 for $category!";
863 }
864
865 my $emarch = Jeweler::get_arch ('emerald');
866 my $saarch = Jeweler::get_arch ('sapphire');
867 my $pearch = Jeweler::get_arch ('pearl');
868 my $ruarch = Jeweler::get_arch ('ruby');
869 my $diarch = Jeweler::get_arch ('gem');
870
871 my $sumvalue = $diarch->value * $diamonds;
872
873 $cost->{emerald} += ceil (($sumvalue * $stat_split->[0]) / max (1, $emarch->value));
874 $cost->{sapphire} += ceil (($sumvalue * $stat_split->[1]) / max (1, $saarch->value));
875 $cost->{pearl} += ceil (($sumvalue * $stat_split->[2]) / max (1, $pearch->value));
876 $cost->{ruby} += ceil (($sumvalue * $stat_split->[3]) / max (1, $ruarch->value));
877 $cost->{gem} += ceil (($sumvalue * $stat_split->[4]) / max (1, $diarch->value));
878}
879
880
881
284package Jeweler::Util; 882package Jeweler::Util;
883use strict;
285 884
286=head2 Util 885=head2 Util
287 886
288Some utility functions for the Jeweler skill. 887Some utility functions for the Jeweler skill.
289 888
290=over 4 889=over 4
291 890
292=item remove ($object) 891=item remove ($object[, $nrof])
293 892
294Removes the C<$object> and it's inventory recursivley from the game. 893Removes the C<$object>. If C<$nrof> is given, remove only C<$nrof> objects.
894The returnvalue is the number of 'single' objects that couldn't be removed.
295 895
296=cut 896=cut
297 897
298sub remove { 898sub remove {
299 my ($obj) = @_; 899 my ($obj, $nrof) = @_;
300 900
301 remove ($_) for ($obj->inv); 901#XXX: waht about this: remove ($_) for ($obj->inv) ?
902
903 my $cnt = $obj->nrof - (1 * $nrof);
904
905 if ($cnt > 0) {
906 $obj->set_nrof ($cnt);
907 return 0;
908 } else {
302 $obj->remove; 909 $obj->remove;
303 $obj->free; 910 $obj->free;
911 return $cnt;
912 }
913}
914
915sub grep_for_match {
916 my ($thing, @matchar) = @_;
917
918 my $i = 0;
919 for my $match (@matchar) {
920 if ($match =~ m/^\s*$/) {
921 $i++;
922 next;
923 }
924
925 if ($i % 3 == 0) {
926 $thing->name eq $match
927 and return 1;
928 } elsif ($i % 3 == 1) {
929 $thing->title eq $match
930 and return 1;
931 } else { # $i % 3 == 2
932 $thing->archetype->name eq $match
933 and return 1;
934 }
935 $i++;
936 }
937 return 0;
304} 938}
305 939
306=back 940=back
307 941
308=back 942=back

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines