ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/maps/perl/minesweeper.ext
Revision: 1.8
Committed: Mon Aug 21 04:04:17 2006 UTC (17 years, 9 months ago) by root
Branch: MAIN
Changes since 1.7: +3 -2 lines
Log Message:
*** empty log message ***

File Contents

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