ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/maps/perl/minesweeper.ext
Revision: 1.9
Committed: Mon Aug 21 05:22:52 2006 UTC (17 years, 9 months ago) by root
Branch: MAIN
Changes since 1.8: +5 -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, $damned) = split /,/, $teleport;
12 my $pl = cf::player::find $ob->{player};
13
14 $pl->ob->transfer ($x, $y);
15 $pl->set_savebed ($pl->ob->map->path, $x, $y)
16 if $ob->{options}{"set_savebed_$status"};
17 }
18 }
19
20 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 result $meta, "failure"
34 if $meta->{todo};
35 } else {
36 $meta->{todo}--;
37 # if <= 0, finished
38
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 $who->remove;
60 $who->free;
61 }
62
63 1
64 }
65
66 sub on_time {
67 my ($event, $who) = @_;
68
69 if (my $queue = $who->{queue}) {
70 my $count = 4;
71
72 while (@$queue) {
73 my $i = int rand @$queue;
74 my $ob = splice @$queue, $i, 1, ();
75
76 next if $ob->{visible};
77
78 apply $ob
79 or next;
80
81 result $who, "success"
82 unless $who->{todo};
83
84 $count--
85 or last;
86 }
87 } else {
88 # generate minesweeper field
89 my %arg = split /(?:\s+|=)/, $event->options;
90
91 $who->{options} = \%arg;
92 $who->{queue} = [];
93
94 my $map = $who->{map} = [];
95
96 for my $x (0 .. $arg{width} - 1) {
97 for my $y (0 .. $arg{height} - 1) {
98 my $ob = $map->[$x][$y] = cf::object::new "minesweeper-unknown";
99 $ob->set_name ("apply to try your luck or intelligence");
100 Scalar::Util::weaken ($ob->{meta} = $who);
101
102 my $ev = cf::object::new "event_apply";
103 $ev->set_title ("perl");
104 $ev->set_slaying ("minesweeper");
105 $ev->insert_in_ob ($ob);
106
107 $ob->insert_ob_in_map_at ($who->map, undef, cf::INS_ABOVE_FLOOR_ONLY,
108 $who->x + $x, $who->y + $y);
109 }
110 }
111
112 # #tiles that need to be uncovered
113 $who->{todo} = $arg{width} * $arg{height} - $arg{bombs};
114
115 for (1 .. $arg{bombs}) {
116 my $x = int rand $arg{width};
117 my $y = int rand $arg{height};
118
119 redo if $map->[$x][$y]{bomb};
120
121 $map->[$x][$y]{bomb} = 1;
122 }
123 }
124 }
125
126 sub on_apply {
127 my ($event, $ob, $who) = @_;
128
129 $ob->{meta}{player} = $who->name;
130 push @{$ob->{meta}{queue}}, $ob;
131
132 1
133 }
134
135