File Coverage

blib/lib/Games/RolePlay/MapGen/Generator.pm
Criterion Covered Total %
statement 78 78 100.0
branch 14 26 53.8
condition 2 6 33.3
subroutine 15 15 100.0
pod 0 12 0.0
total 109 137 79.5


line stmt bran cond sub pod time code
1             # vi:tw=0 syntax=perl:
2              
3             package Games::RolePlay::MapGen::Generator;
4              
5 17     17   13031 use common::sense;
  17         37  
  17         149  
6 15     15   772 use Carp;
  15         31  
  15         24372  
7              
8             our @ISA;
9              
10             1;
11              
12             # new {{{
13             sub new {
14 8     8 0 24 my $class = shift;
15 8         111 my $this = bless {o => {@_}}, $class;
16              
17 8         277 $this->{plugins} = {
18             pre => [ ], # after the entire map is built, this executes on the topnode (before treasure and traps are added)
19              
20             trap => [ ],
21             door => [ ],
22             encr => [ ],
23             tres => [ ],
24              
25             post => [ ], # after the entire map is built and treasure traps and doors are added
26             };
27              
28 8         85 return $this;
29             }
30             # }}}
31             # gen_opts {{{
32             sub gen_opts {
33 22     22 0 39 my $this = shift;
34 22         97 my $opts = {@_};
35              
36 22         37 for my $k (keys %{ $this->{o} }) {
  22         116  
37 346 100       977 $opts->{$k} = $this->{o}{$k} if not exists $opts->{$k};
38             }
39              
40 22         92 return $opts;
41             }
42             # }}}
43             # go {{{
44             sub go {
45 8     8 0 17 my $this = shift;
46 8         94 my $opts = $this->gen_opts(@_);
47              
48 8         101 $this->gen_bounding_size( $opts );
49              
50 8 50 33     78 croak "ERROR: bounding_box is a required option for " . ref($this) . "::go()" unless $opts->{x_size} and $opts->{y_size};
51 8 50       35 croak "ERROR: num_rooms is a required option for " . ref($this) . "::go()" unless $opts->{num_rooms};
52              
53 8 50       34 $opts->{min_room_size} = "2x2" unless $opts->{min_room_size};
54 8 50       159 $opts->{max_room_size} = "9x9" unless $opts->{max_room_size};
55              
56 8 50 33     108 croak "ERROR: room sizes are of the form 9x9, 3x10, 2x2, etc" unless $opts->{min_room_size} =~ m/^\d+x\d+$/ and $opts->{max_room_size} =~ m/^\d+x\d+$/;
57              
58 8         49 my ($map, $groups) = $this->genmap( $opts );
59              
60 8         186 my $changed_options = $this->post_genmap( $opts, $map, $groups );
61              
62 8         114 return ($map, $groups, $changed_options);
63             }
64             # }}}
65             # gen_bounding_size {{{
66             sub gen_bounding_size {
67 8     8 0 19 my $this = shift;
68 8         16 my $opts = shift;
69              
70 8 50       52 if( $opts->{bounding_box} ) {
71 8 50       70 die "ERROR: illegal bounding box description '$opts->{bounding_box}'" unless $opts->{bounding_box} =~ m/^(\d+)x(\d+)/;
72 8         31 $opts->{x_size} = $1;
73 8         34 $opts->{y_size} = $2;
74             }
75             }
76             # }}}
77             # post_genmap {{{
78             sub post_genmap {
79 8     8 0 25 my $this = shift;
80 8         24 my ($opts, $map, $groups) = @_;
81              
82 8         101 $this->pre( $opts, $map, $groups );
83              
84 8         174 $this->doorgen( $opts, $map, $groups );
85 8         202 $this->trapgen( $opts, $map, $groups );
86 8         129 $this->encountergen( $opts, $map, $groups );
87 8         96 $this->treasuregen( $opts, $map, $groups );
88              
89 8         117 $this->post( $opts, $map, $groups );
90              
91 8         20 my $changed_options = {};
92 8         75 for my $k (keys %$opts) {
93 140 50       613 $changed_options->{$k} = $opts->{$k} if $opts->{$k} ne $this->{o};
94             }
95              
96 8         40 return $changed_options;
97             }
98             # }}}
99              
100             # Meant to be overloaded elsewhere:
101 8     8 0 32 sub trapgen { my $this = shift; $_->trapgen(@_) while $_ = shift @{$this->{plugins}{trap}} }
  8         23  
  8         58  
102 8     8 0 24 sub doorgen { my $this = shift; $_->doorgen(@_) while $_ = shift @{$this->{plugins}{door}} }
  8         20  
  12         2248  
103 8     8 0 24 sub encountergen { my $this = shift; $_->encountergen(@_) while $_ = shift @{$this->{plugins}{encr}} }
  8         20  
  8         93  
104 8     8 0 32 sub treasuregen { my $this = shift; $_->treasuregen(@_) while $_ = shift @{$this->{plugins}{tres}} }
  8         20  
  8         58  
105 8     8 0 22 sub post { my $this = shift; $_->post(@_) while $_ = shift @{$this->{plugins}{post}} }
  8         19  
  8         56  
106 8     8 0 31 sub pre { my $this = shift; $_->pre(@_) while $_ = shift @{$this->{plugins}{pre} } }
  8         20  
  10         93  
107              
108             # add_plugin {{{
109             sub add_plugin {
110 6     6 0 14 my $this = shift;
111 6         14 my $plugin = shift;
112              
113             ## This is a nice idea, but it actually sux0rs ... toast
114             ## # Check to see if it works
115             ## push @ISA, $plugin;
116             ## $Games::RolePlay::MapGen::Generator::doorgen =
117              
118 6     4   509 eval "use $plugin";
  4         3609  
  4         98  
  4         272  
119 6 50       48 croak $@ if $@;
120              
121 6         10 my $obj;
122 6         551 eval "\$obj = new $plugin";
123 6 50       63 croak $@ if $@;
124              
125 6 50       46 croak "uesless plugin" unless int(@$obj) > 0;
126 6         16 for my $e (@$obj) {
127 6         18 my $pt = $this->{plugins}{$e};
128 6 50       26 croak "plugin hooks unknown event" unless ref($pt) eq "ARRAY";
129 6         57 push @$pt, $obj;
130             }
131             }
132             # }}}