ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/maps/perl/minesweeper.ext
Revision: 1.15
Committed: Tue Dec 12 16:59:34 2006 UTC (17 years, 5 months ago) by root
Branch: MAIN
Changes since 1.14: +1 -2 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #! perl
2    
3     use Scalar::Util;
4    
5     # minesweeper extension. dumb.
6    
7 root 1.3 sub result {
8     my ($ob, $status) = @_;
9    
10     if (my $teleport = $ob->{options}{"teleport_$status"}) {
11 root 1.9 my ($x, $y, $damned) = split /,/, $teleport;
12     my $pl = cf::player::find $ob->{player};
13 root 1.3
14 root 1.9 $pl->ob->transfer ($x, $y);
15 root 1.14 $pl->savebed ($pl->ob->map->path, $x, $y)
16 root 1.9 if $ob->{options}{"set_savebed_$status"};
17 root 1.3 }
18     }
19    
20 root 1.2 sub apply {
21     my ($who) = @_;
22    
23     my $meta = $who->{meta}
24     or return;
25    
26     my $map = $meta->{map};
27    
28     my ($x, $y) = ($who->x - $meta->x, $who->y - $meta->y);
29    
30     $who->{visible} = 1;
31    
32     if ($who->{bomb}) {
33 root 1.8 result $meta, "failure"
34     if $meta->{todo};
35 root 1.2 } else {
36     $meta->{todo}--;
37 root 1.8 # if <= 0, finished
38 root 1.2
39     my @neigh;
40    
41     for my $y ($y - 1 .. $y + 1) {
42     next if $y < 0 || $y > $#{$map->[0]};
43     for my $x ($x - 1 .. $x + 1) {
44     next if $x < 0 || $x > $#$map;
45     push @neigh, $map->[$x][$y];
46     }
47     }
48    
49     my $bombs = grep $_->{bomb}, @neigh;
50    
51     my $ob = $map->[$x][$y] = cf::object::new "minesweeper-$bombs";
52    
53     $ob->insert_ob_in_map_at ($who->map, undef, cf::INS_ABOVE_FLOOR_ONLY,
54     $who->x, $who->y);
55    
56     push @{ $meta->{queue} }, grep !$_->{visible}, @neigh
57     unless $bombs;
58    
59 root 1.15 $who->destroy;
60 root 1.2 }
61 root 1.6
62     1
63 root 1.2 }
64    
65 root 1.12 cf::register_attachment minesweeper =>
66 root 1.13 on_tick => sub {
67 root 1.12 my ($self) = @_;
68 root 1.1
69 root 1.13 if (my $queue = $self->{queue}) {
70     my $count = 4;
71 root 1.1
72 root 1.13 while (@$queue) {
73     my $i = int rand @$queue;
74     my $ob = splice @$queue, $i, 1, ();
75 root 1.1
76 root 1.13 next if $ob->{visible};
77 root 1.1
78 root 1.13 apply $ob
79     or next;
80 root 1.2
81 root 1.13 result $self, "success"
82     unless $self->{todo};
83 root 1.2
84 root 1.13 $count--
85     or last;
86     }
87     } else {
88     my %arg = %{ $self->{options} = delete $self->{minesweeper} };
89     $self->{queue} = [];
90    
91     my $map = $self->{map} = [];
92    
93     for my $x (0 .. $arg{width} - 1) {
94     for my $y (0 .. $arg{height} - 1) {
95     my $ob = $map->[$x][$y] = cf::object::new "minesweeper-unknown";
96 root 1.14 $ob->name ("apply to try your luck or intelligence");
97 root 1.13 Scalar::Util::weaken ($ob->{meta} = $self);
98    
99     $ob->attach ("minesweeper_field");
100     $ob->insert_ob_in_map_at ($self->map, undef, cf::INS_ABOVE_FLOOR_ONLY,
101     $self->x + $x, $self->y + $y);
102     }
103     }
104 root 1.1
105 root 1.13 # #tiles that need to be uncovered
106     $self->{todo} = $arg{width} * $arg{height} - $arg{bombs};
107 root 1.12
108 root 1.13 for (1 .. $arg{bombs}) {
109     my $x = int rand $arg{width};
110     my $y = int rand $arg{height};
111 root 1.12
112 root 1.13 redo if $map->[$x][$y]{bomb};
113 root 1.12
114 root 1.13 $map->[$x][$y]{bomb} = 1;
115     }
116 root 1.12 }
117 root 1.1
118 root 1.12 cf::override;
119     },
120     ;
121    
122     cf::register_attachment minesweeper_field =>
123     on_apply => sub {
124     my ($ob, $who) = @_;
125    
126     $ob->{meta}{player} = $who->name;
127     push @{$ob->{meta}{queue}}, $ob;
128    
129     cf::override 1;
130     },
131     ;
132 root 1.1