ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/lib/collect.pl.in
Revision: 1.8
Committed: Sun May 27 02:26:20 2007 UTC (16 years, 11 months ago) by root
Branch: MAIN
CVS Tags: HEAD
Changes since 1.7: +0 -0 lines
State: FILE REMOVED
Log Message:
2.1 cleanups

File Contents

# Content
1 #!@PERL@
2
3 require "util.pl";
4
5 if ($#ARGV >= 0) {
6 if ($ARGV[0] =~ m/^--?[hH](elp)?$/) {
7 die ("\nUSAGE: perl collect.pl ARCHDIR\n".
8 "\nWhere ARCHDIR is the directory where you stored the ".
9 "raw archetypes.\n".
10 "This script will then create these files:\n".
11 "archetypes,bmaps,bmaps.paths,faces,smooth,treasures.bld,animations.\n"
12 )
13 }
14 }
15
16 # archonly is used to only build the archetypes. I find this
17 # very handy if I know I've only changed .arc files - I don't want
18 # to rebuild the other files, because now cvs tries to do diffs
19 # on them as well as commit them, even if there are no changes.
20 $archonly = 0;
21 if ($#ARGV >= 1) {
22 if ($ARGV[1] eq "ARCHONLY") { $archonly = 1; }
23 else {print "Ignoring unknown option: $ARGV[1]\n"; }
24 }
25
26
27 $root = $ARGV[0];
28 $archetypes = "archetypes";
29 $bmaps = "bmaps";
30 $faces = "faces";
31 $treasures = "treasures.bld";
32 $animations = "animations";
33 $paths = $bmaps."."."paths";
34 $faceExt = "\\.[a-zA-Z0-9][A-Z0-9][A-Z0-9]";
35 $smooth = "smooth";
36
37 ### main
38 &info("looking ...");
39 &traverse($root);
40
41 $attacktype{ 'physical' } = ( 1 << 0 );
42 $attacktype{ 'magic' } = ( 1 << 1 );
43 $attacktype{ 'fire' } = ( 1 << 2 );
44 $attacktype{ 'electricity' } = ( 1 << 3 );
45 $attacktype{ 'cold' } = ( 1 << 4 );
46 $attacktype{ 'confusion' } = ( 1 << 5 );
47 $attacktype{ 'acid' } = ( 1 << 6 );
48 $attacktype{ 'drain' } = ( 1 << 7 );
49 $attacktype{ 'weaponmagic' } = ( 1 << 8 );
50 $attacktype{ 'ghosthit' } = ( 1 << 9 );
51 $attacktype{ 'poison' } = ( 1 << 10 );
52 $attacktype{ 'slow' } = ( 1 << 11 );
53 $attacktype{ 'paralyze' } = ( 1 << 12 );
54 $attacktype{ 'turnundead' } = ( 1 << 13 );
55 $attacktype{ 'fear' } = ( 1 << 14 );
56 $attacktype{ 'cancellation' } = ( 1 << 15 );
57 $attacktype{ 'deplete' } = ( 1 << 16 );
58 $attacktype{ 'death' } = ( 1 << 17 );
59 $attacktype{ 'chaos' } = ( 1 << 18 );
60 $attacktype{ 'counterspell' } = ( 1 << 19 );
61 $attacktype{ 'godpower' } = ( 1 << 20 );
62 $attacktype{ 'holyword' } = ( 1 << 21 );
63 $attacktype{ 'blind' } = ( 1 << 22 );
64 $attacktype{ 'internal' } = ( 1 << 23 );
65 $attacktype{ 'lifestealing' } = ( 1 << 24 );
66 $attacktype{ 'disease' } = ( 1 << 25 );
67
68 &info("writing ...$archetypes");
69 open(ARCH,">".$archetypes) || &die("cannot open ".$archetypes);
70 &archsOut($root);
71 close(ARCH);
72
73
74 if (!$archonly) {
75 &info("$bmaps");
76 open(BMAPS,">".$bmaps) || &die("cannot open ".$bmaps);
77 &bmapsOut;
78 close(BMAPS);
79
80 open(BMAPS,">".$paths) || &die("cannot open ".$paths);
81 &pathsOut;
82 close(BMAPS);
83
84 &info("$faces");
85 open(FACES,">".$faces) || &die("cannot open ".$faces);
86 &facesOut;
87 close(FACES);
88
89 &info("$smooth");
90 open(SMOOTHS,">".$smooth) || &die("cannot open ".$smooth);
91 &smoothOut;
92 close(SMOOTHS);
93
94 &info("$treasures");
95 # We still support the old consolidated treasure information
96 # so copy it over.
97 open(TREASURES,">".$treasures) || &die("cannot open ".$treasures);
98 print TREASURES "#
99 # Do not modify this file - any changes will get overwritten.
100 # instead, modify the treasures file or the .trs file in the
101 # arch directory.\n#
102 ";
103
104 open(TR, "<treasures");
105 while (<TR>) {
106 print TREASURES $_;
107 }
108 close(TR);
109 print TREASURES "#\n# Start of collected .trs files\n#\n";
110
111 &treasuresOut;
112 close(TREASURES);
113
114 &info("$animations");
115 open(ANIM,">".$animations) || &die("cannot open ".$animations);
116 &animOut;
117 close(ANIM);
118 }
119
120
121 &stats;
122 exit 0;
123
124 sub traverse {
125 local($dir) = shift;
126 local($file,$name);
127 local( $tfile);
128
129 opendir(THISDIR, $dir) || die "couldn't open $dir";
130 local(@allfiles) = readdir(THISDIR);
131 closedir(THISDIR);
132
133 foreach $tfile (sort @allfiles) {
134 next if $tfile =~ /^\./;
135 $file = $dir."/".$tfile;
136 $name = &basename($file,""); # DIR
137
138 if( -d $file && $name ne "dev" && $name ne "trashbin" && $name ne "CVS" ) {
139 &traverse($file);
140 } elsif ( -d $file && ( $name eq "dev" || $name eq "trashbin" ) ) {
141 # Empty directive to prevent warnings below
142 } elsif( $file =~ /.*\.arc$/) { # ARCHETYPE
143 $archsNum++;
144 push(@archs,$file);n
145 } elsif( $name =~ /(\S+)\.base($faceExt)\.png$/) { # FACE
146 $facesNum++;
147 $im_name = "$1$2";
148 &warn("duplicate face $im_name in ".$dir." and $faces{$im_name}")
149 if $faces{$im_name};
150 $faces{$im_name} = $dir."/".$im_name;
151
152 } elsif ( $file =~ /.*\.face$/) { # Face information file
153 $facesFileNum++;
154 push(@face_files, $file);
155 } elsif ( $file =~ /.*\.trs$/) { # Treasure information file
156 push(@treasure_files, $file);
157 }
158 elsif ( $file =~ /\.png$/ || $file =~ /\.xpm$/ || $file =~ /$faceExt$/) {
159 # we cover many files we probably shouldn't, but oh well.
160 # we just don't want complaints about all of these.
161 }
162 # ignore a couple of the more common 'junk' files that are not
163 # really junk.
164 elsif (($name ne "README") && ($name ne "CVS")) {
165 $trashNum++;
166 print "Warning: $file might be a junk file\n";
167 }
168 }
169 }
170
171 sub storeFaceInfo {
172 local($lface,@values) = @_;
173
174 if ($values[0] ne "") {
175 # blank.x11 is a special case -
176 # since no foreground pixels will actually be drawn, foreground colors is
177 # not relevant. Several monsters use blank.x11 as part of their
178 # animation to make them appear invisible, but have some other
179 # foreground color set.
180 # Same applies to empty also.
181 if ($fg{$lface} && $fg{$lface} ne $values[0] && $lface ne "blank.x11"
182 && $lface ne "empty.x11") {
183 &warn($arch." duplicate fg color ".$fg{$lface}."/".$values[0]." face ".$lface);
184 } else {
185 $fg{$lface} = $values[0];
186 }
187 }
188 if ($values[1] ne "") {
189 if ($bg{$lface} && $bg{$lface} ne $values[1]) {
190 &warn($arch." duplicate bg color ".$bg{$lface}."/".$values[1]." face ".$lface);
191 } else {
192 $bg{$lface} = $values[1];
193 }
194 }
195 if ($values[2] ne "" && $lface ne "blank.x11" && $lface ne "empty.x11") {
196 # blank.x11 is a special case - see above explanation
197 # Its visibility is always 0.
198 if ($visibility{$lface} && $visibility{$lface} ne $values[2]) {
199 &warn($arch." duplicate visibilty ".$visibility{$lface}."/".$values[2]." face ".$lface);
200 } else {
201 $visibility{$lface} = $values[2];
202 }
203 }
204 if ($values[3] ne "" && lface ne "blank.x11" && $lface ne "empty.x11") {
205 if ($magicmap{$lface} && $magicmap{$lface} ne $values[3]) {
206 &warn($arch." duplicate magicmap color ".$magicmap{$lface}."/".$values[3]." face ".$lface);
207 } else {
208 $magicmap{$lface} = $values[3];
209 }
210 }
211 if ($values[4] ne "") {
212 if ($floor{$lface} && $floor{$lface} ne $values[4]) {
213 &warn($arch." duplicate floor information ".$floor{$lface}."/".$values[4]." face ".$lface);
214 } else {
215 $floor{$lface} = $values[4];
216 }
217 }
218 }
219
220
221 sub archsOut {
222 local($dir) = shift;
223
224 foreach $arch (@archs) {
225 # Assume the filename $arch begins with $dir. Assign all path name
226 # components after $dir to $pathto.
227 if($arch =~ /^\Q$dir\E\/(.*)\/[^\/]*[.]arc$/) {
228 $pathto = $1;
229 } else {
230 &warn("cannot determine editor_folder from arch '$arch'");
231 $pathto = "";
232 }
233 open(ARC,$arch) || &die("cannot open ".$arch);
234 line: while(<ARC>) {
235 chop;
236 if (/^\s*(?:#.*|)$/) {
237 # comment, skip line
238 $commentNum++;
239 next line;
240 }
241 ($var, @values) = split;
242 if ($var =~ /^[Oo]bject$/) {
243 $lface[0] = "";
244 $#lface = 0;
245 $lfg = "";
246 $lbg = "";
247 $lvis = "";
248 $mm = "";
249 $floor = "";
250 $walkon = 0;
251 $nopick = 0;
252 $arch = join "_", @values;
253 } elsif ($var eq "end") {
254 if ($#lface !=0) {
255 $#lface--;
256 foreach $face (@lface) {
257 &storeFaceInfo($face, $lfg, $lbg, $lvis,$mm,$floor);
258 }
259 }
260 if ($walkon && !$nopick) {
261 &warn("File $arch has an object with walk_on set which can be picked up\n");
262 }
263 print ARCH "editor_folder $pathto\n" if $pathto ne "";
264 # Process the color/face info now
265 } elsif ($var eq "color_fg") {
266 $lfg = $values[0];
267 next line;
268 } elsif ($var eq "color_bg") {
269 $lbg = $values[0];
270 next line;
271 } elsif ($var eq "visibility") {
272 $lvis = $values[0];
273 next line;
274 } elsif ($var eq "magicmap") {
275 $mm = $values[0];
276 next line;
277 } elsif ($var eq "attacktype") {
278 $at = 0;
279 foreach $t ( @values ) {
280 if ( $t =~ /^\d+$/ ) {
281 $at |= $t;
282 } else {
283 if ( defined( $attacktype{ $t } ) ) {
284 $at |= $attacktype{ $t };
285 } else {
286 &warn($arch . " has invalid attacktype " . $t);
287 }
288 }
289 }
290 $_ = $var . ' ' . $at;
291 } elsif ($var eq "is_floor") {
292 $floor = $values[0];
293 # is_floor is also needed for archs, so let it pass
294 # through
295 } elsif ($var eq "no_pick") {
296 $nopick = $values[0];
297 } elsif ($var eq "walk_on") {
298 $walkon = $values[0];
299 } elsif ($var eq "face" && ! $faces{$values[0]}) {
300 &warn($arch." is missing face ".$values[0])
301 } elsif ($var eq "face") {
302 $lface[$#lface++] = $values[0]
303 } elsif ($var eq "anim") {
304 if ($anim{$arch}) {
305 &warn("$arch is a duplicate animation name");
306 $anim{$arch}="";
307 }
308 while (<ARC>) {
309 chomp;
310 $var = $_;
311 last if ($var =~ "mina\s*");
312 if ($var =~ /facings \S+$/) { }
313 elsif (! $faces{$var}) {
314 &warn($arch." is missing face ".$var);
315 }
316 else {
317 $lface[$#lface++] = $var;
318 }
319 $anim{$arch} .= "$var\n";
320 }
321 print ARCH "animation $arch\n";
322 next line; # don't want the mina
323 } elsif ($var eq "smoothface") {
324 if ($smoothing{$values[0]} && ($smoothing{$values[0]} ne $values[1])) {
325 &warn($arch." duplicate smoothface for ".$values[0].": ".$smoothing{$values[0]}." and ".$values[1]);
326 } elsif ( ($values[0] eq "") || ($values[1] eq "")) {
327 &warn ($arch." incomplete smoothface entry found: ".$values[0]." ".$values[1]);
328 } else {
329 $smoothing{$values[0]}=$values[1]
330 }
331 next line; #smoothface must be excluded from archetype file
332 }
333 print ARCH $_,"\n";
334 }
335 close(ARC);
336 }
337 }
338
339 sub pline {
340 local($face) = shift;
341 print BMAPS sprintf("%05d",$idx++)," ",$face,"\n";
342 }
343
344 sub opline {
345 local($face) = shift;
346 print BMAPS sprintf("\\%05d",$idx++),"\t",$face,"\n";
347 }
348
349 sub pheader {
350 print BMAPS "# This file is generated by $0, do not edit\n";
351 }
352
353 sub bmapsOut {
354 &pheader;
355 $idx = 0;
356 &pline("bug.x11");
357 foreach $face (sort(keys %faces)) {
358 &pline($face) if $face !~ /bug\.x11/;
359 }
360 }
361
362 sub pathsOut {
363 &pheader;
364 $idx = 0;
365 &opline($root."/system/bug.x11");
366 foreach $face (sort(keys %faces)) {
367 &opline($faces{$face}) if $faces{$face} !~ /bug\.x11/;
368 }
369 }
370
371 sub treasuresOut {
372 foreach $treasure (@treasure_files) {
373 open(TREAS, $treasure) || &die("cannot open ".$treasure);
374 while(<TREAS>) {
375 if (! /^\s*$/) {
376 print TREASURES $_;
377 }
378 }
379 close(FACE);
380 }
381 }
382
383 sub facesOut {
384 foreach $face (@face_files) {
385 open(FACE, $face) || &die("cannot open ".$face);
386 while(<FACE>) {
387 chop;
388 local ($var, @values) = split;
389 if ($var eq "face") {
390 $lface = $values[0];
391 $lfg = "";
392 $lbg = "";
393 $lvis = "";
394 $mm = "";
395 $floor = "";
396 }
397 elsif ($var eq "color_fg") {
398 $lfg = $values[0];
399 }
400 elsif ($var eq "color_bg") {
401 $lbg = $values[0];
402 }
403 elsif ($var eq "visibility") {
404 $lvis = $values[0];
405 }
406 elsif ($var eq "magicmap") {
407 $mm = $values[0];
408 }
409 elsif ($var eq "is_floor") {
410 $floor = $values[0];
411 }
412 elsif ($var eq "end") {
413 &storeFaceInfo($lface, $lfg, $lbg, $lvis, $mm, $floor);
414 }
415 elsif ($var eq "animation") {
416 $animation=$values[0];
417 if ($anim{$1}) {
418 &warn("$animation is a duplicate animation name");
419 $anim{$animation}="";
420 }
421 while (<FACE>) {
422 chomp;
423 $var = $_;
424 last if ($var =~ /^mina\s*$/);
425 if ($var !~ /^facings/ ) {
426 if (! $faces{$var}) {
427 &warn($arch." is missing face ".$var);
428 }
429 else {
430 $lface[$#lface++] = $var;
431 }
432 }
433 $anim{$animation} .= "$var\n";
434 }
435 next; # don't want the mina
436 }
437 }
438 close(FACE);
439 }
440 print FACES "# This file is generated by $0, do not edit\n";
441 foreach $face (sort(keys %faces)) {
442 if ($fg{$face} ne "" || $bg{$face} ne "" || $visibility{$face} ne "" ||
443 $magicmap{$face} ne "" || $floor{$face} ne "") {
444 print FACES "face ".$face."\n";
445 print FACES "color_fg ".$fg{$face}."\n"
446 if $fg{$face} ne "";
447 print FACES "color_bg ".$bg{$face}."\n"
448 if $bg{$face} ne "";
449 print FACES "visibility ".$visibility{$face}."\n"
450 if $visibility{$face} ne "";
451 print FACES "magicmap ".$magicmap{$face}."\n"
452 if $magicmap{$face} ne "";
453 print FACES "is_floor ".$floor{$face}."\n"
454 if $floor{$face} ne "";
455 print FACES "end\n";
456 }
457 }
458 }
459
460 sub animOut {
461 foreach $anim (sort keys %anim) {
462 print ANIM "anim $anim\n$anim{$anim}mina\n";
463 $animationsNum++;
464 }
465 }
466 sub smoothOut {
467 local ($sm);
468 print SMOOTHS "##########################################################\n";
469 print SMOOTHS "# Do not touch this file. #\n";
470 print SMOOTHS "# It has been generated from the information present #\n";
471 print SMOOTHS "# in the archetype files. #\n";
472 print SMOOTHS "# To add new entries, simply add #\n";
473 print SMOOTHS "# smoothface xxx yyy #\n";
474 print SMOOTHS "# to an archetype and collect.pl will put below an entry #\n";
475 print SMOOTHS "# xxx yyy #\n";
476 print SMOOTHS "##########################################################\n\n";
477 print SMOOTHS "# default smooth. Needed for fallbacking\n";
478 print SMOOTHS "default_smoothed.111 sdefault.001\n";
479 print SMOOTHS "\n# Data extracted from arch files\n";
480 foreach $sm (sort (keys %smoothing)) {
481 print SMOOTHS "$sm $smoothing{$sm}\n";
482 $smoothNum++;
483 }
484 }
485
486 ### print out statical information
487 sub stats {
488 &info(Archs.":\t".$archsNum);
489 &info(Images.":\t".$facesNum);
490 &info(Faces.":\t".$facesFileNum);
491 &info(Animations.":\t".$animationsNum);
492 &info(Treasures.":\t".($#treasure_files+1));
493 &info(Trash.":\t".$trashNum);
494 &info(Smooths.":\t".$smoothNum);
495 &info("Comment lines:\t".$commentNum);
496 }