File Coverage

blib/lib/Games/SMTNocturne/Demons/Demon.pm
Criterion Covered Total %
statement 46 50 92.0
branch 18 22 81.8
condition n/a
subroutine 14 15 93.3
pod 5 10 50.0
total 83 97 85.5


line stmt bran cond sub pod time code
1             package Games::SMTNocturne::Demons::Demon;
2             BEGIN {
3 3     3   100 $Games::SMTNocturne::Demons::Demon::AUTHORITY = 'cpan:DOY';
4             }
5             $Games::SMTNocturne::Demons::Demon::VERSION = '0.02';
6 3     3   16 use strict;
  3         6  
  3         95  
7 3     3   15 use warnings;
  3         5  
  3         105  
8 3     3   6107 use overload '""' => 'to_string', fallback => 1;
  3         3393  
  3         16  
9             # ABSTRACT: an individual demon
10              
11 3     3   4117 use JSON::PP;
  3         62318  
  3         2678  
12              
13              
14             my %DEMONS_BY_NAME = %{ decode_json(do { local $/; }) };
15             for my $name (keys %DEMONS_BY_NAME) {
16             $DEMONS_BY_NAME{$name}{name} = $name;
17             $DEMONS_BY_NAME{$name} = bless $DEMONS_BY_NAME{$name}, __PACKAGE__;
18             }
19             my @DEMONS = sort {
20             $a->level <=> $b->level || $a->name cmp $b->name
21             } values %DEMONS_BY_NAME;
22              
23             my %DEMONS_BY_TYPE;
24             for my $name (keys %DEMONS_BY_NAME) {
25             my $demon = $DEMONS_BY_NAME{$name};
26             push @{ $DEMONS_BY_TYPE{$demon->type} ||= [] }, $demon;
27             }
28             for my $type (keys %DEMONS_BY_TYPE) {
29             my $demons = $DEMONS_BY_TYPE{$type};
30             @$demons = sort { $a->level <=> $b->level } @$demons;
31             }
32              
33             sub from_name {
34 2723     2723 0 4499 my ($class, $name) = @_;
35              
36 2723 50       9485 die "unknown demon $name" unless $DEMONS_BY_NAME{$name};
37              
38 2723         19997 return $DEMONS_BY_NAME{$name};
39             }
40              
41             sub all_demons {
42 184     184 0 77921 my $class = shift;
43 184         3701 return @DEMONS;
44             }
45              
46             sub from_fusion_stats {
47 104407     104407 0 184364 my ($class, $options) = @_;
48              
49 104407 50       385208 die "unknown type $options->{type}"
50             unless $DEMONS_BY_TYPE{$options->{type}};
51              
52 104407         124371 my @possible = @{ $DEMONS_BY_TYPE{$options->{type}} };
  104407         384726  
53              
54 104407 100       398132 @possible = grep { $_->fusion_type eq $options->{fusion_type} } @possible
  371626         814610  
55             if $options->{fusion_type};
56              
57 104407 100       137618 my %bosses = map { $_ => 1 } @{ $options->{bosses} || [] };
  169         685  
  104407         598632  
58 104407 100       207128 @possible = grep { !$_->boss || $bosses{$_->name} } @possible;
  694311         1466124  
59              
60 104407         173484 my $found_idx;
61 104407         268510 for my $i (0..$#possible) {
62 430309         556928 $found_idx = $i;
63 430309         622953 my $demon = $possible[$i];
64 430309 100       976188 last if $demon->level >= $options->{level};
65             }
66              
67 104407 100       325924 if ($options->{offset}) {
68 4708 100       10631 $found_idx += $options->{offset} eq 'up' ? 1 : -1;
69 4708 100       9113 $found_idx = 0 if $found_idx < 0;
70 4708 100       11369 $found_idx = $#possible if $found_idx > $#possible;
71             }
72              
73 104407         680980 return $possible[$found_idx];
74             }
75              
76             sub from_type {
77 0     0 0 0 my ($class, $type) = @_;
78              
79 0 0       0 die "unknown type $type" unless $DEMONS_BY_TYPE{$type};
80              
81 0         0 return @{ $DEMONS_BY_TYPE{$type} };
  0         0  
82             }
83              
84              
85 694351     694351 1 2763167 sub boss { $_[0]->{boss} }
86 371626     371626 1 1351282 sub fusion_type { $_[0]->{fusion_type} }
87 878681     878681 1 4440361 sub level { $_[0]->{level} }
88 1105293     1105293 1 6126487 sub name { $_[0]->{name} }
89 1523678     1523678 1 8005150 sub type { $_[0]->{type} }
90              
91             sub to_string {
92 235454     235454 0 133789169 my $self = shift;
93 235454         516585 return '<' . $self->type . ' ' . $self->name . ' (' . $self->level . ')>'
94             }
95              
96              
97             1;
98              
99             =pod
100              
101             =encoding UTF-8
102              
103             =head1 NAME
104              
105             Games::SMTNocturne::Demons::Demon - an individual demon
106              
107             =head1 VERSION
108              
109             version 0.02
110              
111             =head1 SYNOPSIS
112              
113             use Games::SMTNocturne::Demons 'demon';
114              
115             my $pixie = demon('Pixie');
116             say $pixie->name # 'Pixie'
117             say $pixie->level # 2
118             say $pixie->type # 'Fairy'
119              
120             =head1 DESCRIPTION
121              
122             This class represents an individual demon. You typically create instances of
123             this class via the functions in the L package, and
124             you can then look up various data using the accessors here. This class also
125             includes a stringification overload to display the information about the demon
126             in a readable form.
127              
128             =head1 METHODS
129              
130             =head2 boss
131              
132             True if the demon is a boss (meaning that fusing it will not be possible until
133             it has been defeated).
134              
135             =head2 fusion_type
136              
137             How this demon can be created. Can be C for demons that can be fused
138             normally, C for demons that must be evolved, C for demons
139             that require special fusions, and C for demons that require a
140             deathstone in order to fuse.
141              
142             =head2 level
143              
144             The base level of the demon. This level is what is used in the fusion process,
145             regardless of the experience level of the actual demon in your party.
146              
147             =head2 name
148              
149             The name of the demon.
150              
151             =head2 type
152              
153             The type of the demon (C, C, etc).
154              
155             =for Pod::Coverage all_demons
156             from_fusion_stats
157             from_name
158             from_type
159             to_string
160              
161             =head1 AUTHOR
162              
163             Jesse Luehrs
164              
165             =head1 COPYRIGHT AND LICENSE
166              
167             This software is Copyright (c) 2014 by Jesse Luehrs.
168              
169             This is free software, licensed under:
170              
171             The MIT (X11) License
172              
173             =cut
174              
175             __DATA__