File Coverage

blib/lib/Games/SMTNocturne/Demons/FusionChart.pm
Criterion Covered Total %
statement 58 72 80.5
branch 36 46 78.2
condition 10 14 71.4
subroutine 10 12 83.3
pod 0 7 0.0
total 114 151 75.5


line stmt bran cond sub pod time code
1             package Games::SMTNocturne::Demons::FusionChart;
2             BEGIN {
3 3     3   94 $Games::SMTNocturne::Demons::FusionChart::AUTHORITY = 'cpan:DOY';
4             }
5             $Games::SMTNocturne::Demons::FusionChart::VERSION = '0.02';
6 3     3   17 use strict;
  3         5  
  3         86  
7 3     3   14 use warnings;
  3         5  
  3         158  
8              
9 3     3   17 use JSON::PP;
  3         4  
  3         3396  
10              
11             my %FUSION_DATA = %{ decode_json(do { local $/; }) };
12             my %TYPES = %{ $FUSION_DATA{normal_fusions} };
13             my %SPECIAL = %{ $FUSION_DATA{special_fusions} };
14              
15             sub fuse {
16 117697     117697 0 207194 my ($type1, $type2) = @_;
17              
18 117697 50       377764 die "unknown demon type $type1" unless $TYPES{$type1};
19 117697 50       292142 die "unknown demon type $type2" unless $TYPES{$type2};
20              
21 117697         1016036 return $TYPES{$type1}{fusions}{$type2};
22             }
23              
24             sub unfuse {
25 0     0 0 0 my ($type) = @_;
26              
27 0 0       0 die "unknown demon type $type" unless $TYPES{$type};
28              
29 0         0 my @combinations;
30 0         0 for my $type1 (keys %TYPES) {
31 0         0 for my $type2 (grep { $_ ge $type1 } keys %TYPES) {
  0         0  
32 0 0 0     0 push @combinations, [ $type1, $type2 ]
33             if ($TYPES{$type1}{fusions}{$type2} || '') eq $type;
34             }
35             }
36              
37 0         0 return @combinations;
38             }
39              
40             sub fuse_element {
41 4203     4203 0 5913 my ($type) = @_;
42              
43 4203         24829 return $TYPES{$type}{self_fusion};
44             }
45              
46             sub element_fusion {
47 5732     5732 0 13750 my ($type, $element) = @_;
48              
49 5732         22866 return $TYPES{$type}{element_fusions}{$element};
50             }
51              
52             sub fuse_mitama {
53 48     48 0 71 my ($element1, $element2) = @_;
54              
55             # XXX move this into actual data somewhere
56 48         740 my %mitama_fusions = (
57             Erthys => {
58             Aeros => 'Nigi Mitama',
59             Aquans => 'Ara Mitama',
60             Flaemis => 'Kusi Mitama',
61             },
62             Aeros => {
63             Erthys => 'Nigi Mitama',
64             Aquans => 'Kusi Mitama',
65             Flaemis => 'Ara Mitama',
66             },
67             Aquans => {
68             Erthys => 'Ara Mitama',
69             Aeros => 'Kusi Mitama',
70             Flaemis => 'Saki Mitama',
71             },
72             Flaemis => {
73             Erthys => 'Kusi Mitama',
74             Aeros => 'Ara Mitama',
75             Aquans => 'Saki Mitama',
76             },
77             );
78              
79 48         280 return $mitama_fusions{$element1}{$element2};
80             }
81              
82             sub special_fusion {
83 66682     66682 0 93235 my ($demon1, $demon2, $options) = @_;
84              
85             my $find = sub {
86 670320     670320   1218780 my ($need, @have) = @_;
87              
88 670320 100       1945681 if (my $name = $need->{name}) {
    50          
89 403653         849282 return (grep { $_->name eq $name } @have)[0];
  670322         2091960  
90             }
91             elsif (my $type = $need->{type}) {
92 266667 100       787895 my @types = ref($need->{type}) ? @$type : ($type);
93             return (
94 266667         1277225 grep { my $d = $_; grep { $d->type eq $_ } @types } @have
  66         74  
  66         79  
  68         166  
95             )[0];
96             }
97             else {
98 0         0 return undef;
99             }
100 66682         398091 };
101              
102 66682         343539 DEMON: for my $demon (keys %SPECIAL) {
103 1333316         2083090 my $conditions = $SPECIAL{$demon};
104              
105 1333316 100       3305040 if ($conditions->{deathstone}) {
106 600026 100       1685223 next unless $options->{deathstone};
107             }
108              
109 733335 100       1664293 if (my $phases = $conditions->{kagutsuchi}) {
110 84         236 next unless defined $options->{kagutsuchi}
111 45 100 66     105 && grep { $_ == $options->{kagutsuchi} } @$phases;
112             }
113              
114 733308 100       1712337 if (my $sacrifice = $conditions->{sacrifice}) {
115 333319 100       969312 next unless $find->(
    100          
116             $sacrifice,
117             ($options->{sacrifice} ? ($options->{sacrifice}) : ())
118             );
119             }
120              
121 399997 100       832184 if (my $target = $conditions->{target}) {
122 66678 100       200564 if (my $type = $target->{type}) {
    50          
123 18         46 my $fused_type = fuse($demon1->type, $demon2->type);
124 18 100 66     79 next unless $fused_type && $fused_type eq $type;
125             }
126             elsif (my $name = $target->{name}) {
127 66660         423195 require Games::SMTNocturne::Demons;
128 66660         359096 my $fused = Games::SMTNocturne::Demons::fuse(
129             $demon1, $demon2, { %$options, basic => 1 }
130             );
131 66660 100 100     339975 next unless $fused && $fused->name eq $name;
132             }
133             else {
134 0         0 next;
135             }
136             }
137              
138 333351         595393 my @have = ($demon1, $demon2);
139 333351 100 100     1212188 push @have, $options->{sacrifice}
140             if $conditions->{demon3} && $options->{sacrifice};
141              
142 333351         572630 for my $key (qw(demon1 demon2 demon3)) {
143 337063 100       805475 if ($conditions->{$key}) {
144 337001         824783 my $found = $find->($conditions->{$key}, @have);
145 337001 100       1421051 next DEMON unless $found;
146 3690         11027 @have = grep { $_ ne $found } @have;
  7354         21680  
147             }
148             }
149              
150 40         830 return $demon;
151             }
152              
153 66642         706317 return;
154             }
155              
156             sub special_fusion_for {
157 0     0 0   my ($demon) = @_;
158              
159 0 0         return unless $SPECIAL{$demon};
160 0           return { %{ $SPECIAL{$demon} } };
  0            
161             }
162              
163             =for Pod::Coverage
164             element_fusion
165             fuse
166             fuse_element
167             fuse_mitama
168             special_fusion
169             special_fusion_for
170             unfuse
171              
172             =cut
173              
174             1;
175              
176             __DATA__