ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/gde/GCE/Util.pm
Revision: 1.2
Committed: Fri Mar 10 20:32:47 2006 UTC (18 years, 2 months ago) by elmex
Branch: MAIN
Changes since 1.1: +72 -1 lines
Log Message:
implemented edit tools widgets and improved the placement tool

File Contents

# Content
1 package GCE::Util;
2 =head1 NAME
3
4 GCE::Util - some utility functions
5
6 =over 4
7
8 =cut
9
10 use base 'Exporter';
11
12 use Crossfire;
13
14 use Carp ();
15 use Storable;
16 use List::Util qw(min max);
17
18 use Crossfire;
19 use Crossfire::MapWidget;
20
21 our @EXPORT = qw(insert_arch_stack_layer replace_arch_stack_layer new_arch_pb fill_pb_from_arch arch_is_floor stack_find_floor stack_find_wall stack_find arch_is_wall);
22
23 sub new_arch_pb {
24 # this is awful, is this really the best way?
25 my $pb = new Gtk2::Gdk::Pixbuf 'rgb', 1, 8, TILESIZE, TILESIZE;
26 return $pb;
27 }
28
29 sub fill_pb_from_arch {
30 my ($pb, $arch) = @_;
31
32 $pb->fill (0x00000000);
33 $TILE->composite ($pb,
34 0, 0,
35 TILESIZE, TILESIZE,
36 - ($arch->{_face} % 64) * TILESIZE, - TILESIZE * int $arch->{_face} / 64,
37 1, 1, 'nearest', 255
38 );
39 }
40
41 sub classify_arch_layer {
42 my ($arch) = @_;
43
44 if ($arch->{invisible}) { # just a heuristic for 'special' tiles (er. pedestals)
45
46 return 'below';
47
48 } elsif ($arch->{monster}) {
49
50 return 'top';
51
52 } else { # $arch->{is_floor} and all other arches are 'between' monsters and floor
53
54 return 'between';
55 }
56 }
57
58 sub arch_is_floor {
59 my ($a) = @_;
60 return $Crossfire::ARCH{$a->{_name}}->{is_floor};
61 }
62
63 sub arch_is_wall {
64 my ($a) = @_;
65 return $Crossfire::ARCH{$a->{_name}}->{no_pass};
66 }
67
68 sub stack_find {
69 my ($stack, $dir, $pred) = @_;
70
71
72 if ($dir eq 'from_top') {
73 my $i = scalar (@$stack) - 1;
74 if ($i < 0) { $i = 0 }
75
76 for (reverse @$stack) {
77 $pred->($_)
78 and return $i;
79
80 $i--;
81 }
82
83 } else {
84 my $i = 0;
85
86 for (@$stack) {
87 $pred->($_)
88 and return $i;
89
90 $i++;
91 }
92 }
93
94 return 0;
95
96 }
97
98 sub stack_find_floor {
99 my ($stack, $dir) = @_;
100 return stack_find ($stack, $dir, \&arch_is_floor);
101 }
102
103 sub stack_find_wall {
104 my ($stack, $dir) = @_;
105 return stack_find ($stack, $dir, \&arch_is_wall);
106 }
107
108 sub insert_arch_stack_layer {
109 my ($stack, $arch) = @_;
110
111 unless (@$stack) {
112 return [ $arch ];
113 }
114
115 my @outstack;
116
117 my $l = classify_arch_layer ($Crossfire::ARCH{$arch->{_name}});
118
119 if ($l eq 'between') {
120
121 # loop until we reached the first 'between' arch above 'below' arches and the floor
122 while (my $a = shift @$stack) {
123
124 unless ($Crossfire::ARCH{$a->{_name}}->{is_floor}
125 or classify_arch_layer ($Crossfire::ARCH{$a->{_name}}) eq 'below') {
126
127 unshift @$stack, $a;
128 last;
129 }
130
131 push @outstack, $a;
132 }
133
134 # ignore duplicates
135 # FIXME: Broken if non-floor are drawn (too tired to fix)
136 return [ @outstack, @$stack ]
137 if @outstack and $outstack[-1]->{_name} eq $arch->{_name};
138
139 push @outstack, ($arch, @$stack);
140
141 } elsif ($l eq 'top') {
142
143 # ignore duplicates
144 return [ @$stack ]
145 if $stack->[-1]->{_name} eq $arch->{_name};
146
147 @outstack = (@$stack, $arch);
148
149 } else {
150
151 # ignore duplicates
152 return [ @$stack ]
153 if $stack->[0]->{_name} eq $arch->{_name};
154
155 @outstack = ($arch, @$stack);
156 }
157
158 return \@outstack;
159 }
160
161 sub replace_arch_stack_layer {
162 my ($stack, $arch) = @_;
163
164 my @outstack;
165
166 my $l = classify_arch_layer ($Crossfire::ARCH{$arch->{_name}});
167
168 if ($l eq 'between') {
169
170 while (shift @$stack) {
171 last unless $Crossfire::ARCH{$_->{_name}}->{is_floor};
172 push @outstack, $_;
173 }
174
175 if (@outstack and $Crossfire::ARCH{$outstack[-1]->{_name}}->{is_floor}) {
176 pop @outstack;
177 }
178
179 push @outstack, ($arch, @$stack);
180
181 } elsif ($l eq 'top') {
182
183 @outstack = (@$stack, $arch);
184
185 } else {
186
187 @outstack = ($arch, @$stack);
188 }
189
190 return \@outstack;
191 }
192
193 =head1 AUTHOR
194
195 Marc Lehmann <schmorp@schmorp.de>
196 http://home.schmorp.de/
197
198 Robin Redeker <elmex@ta-sa.org>
199 http://www.ta-sa.org/
200
201 =cut
202 1;