File Coverage

blib/lib/Games/RolePlay/MapGen/GeneratorPlugin/BasicDoors.pm
Criterion Covered Total %
statement 88 88 100.0
branch 38 44 86.3
condition 20 29 68.9
subroutine 6 6 100.0
pod 0 2 0.0
total 152 169 89.9


line stmt bran cond sub pod time code
1             # vi:tw=0 syntax=perl:
2              
3             package Games::RolePlay::MapGen::GeneratorPlugin::BasicDoors;
4              
5 4     4   25 use common::sense;
  4         7  
  4         35  
6 4     4   194 use Carp;
  4         7  
  4         310  
7 4     4   23 use Games::RolePlay::MapGen::Tools qw( roll _door choice );
  4         9  
  4         7576  
8              
9             $Games::RolePlay::MapGen::known_opts{ "open_room_corridor_door_percent" } = { door => 95, secret => 2, stuck => 25, locked => 50 };
10             $Games::RolePlay::MapGen::known_opts{ "closed_room_corridor_door_percent" } = { door => 5, secret => 95, stuck => 10, locked => 30 };
11             $Games::RolePlay::MapGen::known_opts{ "open_corridor_corridor_door_percent" } = { door => 1, secret => 10, stuck => 25, locked => 50 };
12             $Games::RolePlay::MapGen::known_opts{ "closed_corridor_corridor_door_percent" } = { door => 1, secret => 95, stuck => 10, locked => 30 };
13             $Games::RolePlay::MapGen::known_opts{ "max_span" } = 50;
14              
15             1;
16              
17             # new {{{
18             sub new {
19 4     4 0 8 my $class = shift;
20 4         10 my $this = [qw(door)]; # you have to be the types of things you hook
21              
22 4         46 return bless $this, $class;
23             }
24             # }}}
25             # doorgen {{{
26             sub doorgen {
27 4     4 0 12 my $this = shift;
28 4         12 my $opts = shift;
29 4         10 my $map = shift;
30 4         8 my $groups = shift;
31              
32 4         46 my $minor_dirs = {
33             n => [qw(e w)],
34             s => [qw(e w)],
35              
36             e => [qw(n s)],
37             w => [qw(n s)],
38             };
39              
40 4   50     31 my $max_span = $opts->{max_span} / ($opts->{tile_size} || 1);
41 4 50       22 $max_span = 1 unless $max_span > 0;
42              
43             # warn "max_span=$max_span";
44              
45 4         24 for my $i ( 0 .. $#$map ) {
46 100         124 my $jend = $#{ $map->[$i] };
  100         411  
47              
48 100         548 for my $j ( 0 .. $jend ) {
49 2650         10191 my $t = $map->[$i][$j];
50              
51 2650 100       16154 if( $t->{type} ) {
52 1594         2595 for my $dir (qw(n e s w)) { my $opp = $Games::RolePlay::MapGen::opp{$dir};
  6376         10196  
53 6376         20506 my $n = $t->{nb}{$dir};
54 6376 100 100     30149 next unless $n and $n->{type};
55              
56 5506 100       14481 unless( $t->{_bchkt}{$dir} ) {
57 5345         10057 my ($ttype, $ntype) = ($t->{type}, $n->{type});
58              
59 5345 100 100     20120 if( $ttype eq "room" and $ntype eq "room" ) {
60 3804 100       9716 if( $t->{group}{name} eq $n->{group}{name} ) {
61 3683         8255 next;
62              
63             } else {
64 121         179 $ntype = "corridor";
65             }
66             }
67              
68 1662 100       5346 my $tkey = ( $t->{od}{$dir} ? "open" : "closed" );
69 1662         4678 $tkey .= "_" . join("_", reverse sort( $ttype, $ntype ));
70 1662         2063 $tkey .= "_door_percent";
71              
72 1662         2740 my $chances = $opts->{$tkey};
73 1662 50       3398 die "chances error for $tkey" unless defined $chances;
74              
75 1662 100       4973 if( (my $r = roll(1, 10000)) <= (my $c = $chances->{door}*100) ) {
76 56         223 my ($span, $nspn) = $this->_find_span($dir=>$opp, $t=>$n);
77              
78 56         412 $_->{_bchkt}{$dir} = 1 for @$span;
79 56         354 $_->{_bchkt}{$opp} = 1 for @$nspn;
80              
81 56 100       173 next unless @$span <= $max_span;
82              
83 53         194 $_->{od}{$dir} = 0 for @$span;
84 53         214 $_->{od}{$opp} = 0 for @$nspn;
85              
86 53         191 $t = choice(@$span);
87 53         140 $n = $t->{nb}{$dir};
88              
89 53         429 my $d1 = sprintf("%40s: (%5d, %5d)", $tkey, $r, $c);
90 53         175 my $d2 = sprintf("(%2d, %2d, $dir)", $j, $i);
91              
92 159 100       431 $t->{od}{$dir} = $n->{od}{$opp} = &_door(
93              
94 53         204 (map {$_ => ((roll(1, 10000) <= $chances->{$_}*100) ? 1:0) } qw(locked stuck secret)),
95              
96             open_dir => {
97             major => &choice( $dir, $opp ),
98 53         110 minor => &choice( @{$minor_dirs->{$dir}} ),
99             },
100             );
101             }
102              
103             # $t->{_bchkt}{$dir} = 1; # handled above in the span now
104             }
105             }
106             }
107             }
108             }
109              
110 4         26 delete $_->{_bchkt} for map(@$_, @$map); # btw, bchkt stands for: basic doors checked tile [direction]
111             }
112             # }}}
113             # _find_span {{{
114             sub _find_span {
115 56     56   90 my $this = shift;
116 56         80 my $dir = shift;
117 56         69 my $opp = shift;
118 56         67 my $t = shift;
119 56         73 my $n = shift;
120 56         128 my $span = [$t];
121 56         106 my $nspn = [$n];
122              
123 56 50       209 warn "WARNING: something is fishy $t->{x},$t->{y}:$dir nb!> $n->{x},$n->{y}:$opp" unless $t->{nb}{$dir} == $n;
124 56 50       207 warn "WARNING: something is fishy $t->{x},$t->{y}:$dir {x},$n->{y}:$opp" unless $n->{nb}{$opp} == $t;
125              
126 56         185 my ($ud, $pd) = (qw(n s));
127 56 100 100     308 ($ud, $pd) = (qw(e w)) if $dir eq "n" or $dir eq "s";
128              
129 56         77 my $ls = 0;
130 56         165 while( $ls != int @$span ) { $ls = int @$span;
  129         154  
131 129         251 $t = $span->[0];
132 129 50 33     158 $n = $nspn->[0]; warn "WARNING: something is fishy" unless $n->{nb}{$opp} == $t and $t->{nb}{$dir} == $n;
  129         849  
133 129 100 66     621 if( $t->{od}{$ud} == 1 and (my $c = $t->{nb}{$ud}) ) {
134 87 100 66     494 if( $n->{od}{$ud} == 1 and (my $d = $n->{nb}{$ud}) ) {
135 70 100       216 if( $c->{od}{$dir} == 1 ) {
136 56         106 unshift @$span, $c;
137 56         142 unshift @$nspn, $d;
138             }
139             }
140             }
141              
142 129         155 $t = $span->[$#{ $span }];
  129         225  
143 129 50 33     166 $n = $nspn->[$#{ $nspn }]; warn "WARNING: something is fishy" unless $n->{nb}{$opp} == $t and $t->{nb}{$dir} == $n;
  129         199  
  129         794  
144 129 100 66     787 if( $t->{od}{$pd} == 1 and (my $c = $t->{nb}{$pd}) ) {
145 57 100 66     327 if( $n->{od}{$pd} == 1 and (my $d = $n->{nb}{$pd}) ) {
146 38 100       151 if( $c->{od}{$dir} == 1 ) {
147 23         47 push @$span, $c;
148 23         75 push @$nspn, $d;
149             }
150             }
151             }
152             }
153              
154 56         159 return ($span, $nspn);
155             }
156             # }}}
157              
158             __END__