ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/lib/collect.pl.in
Revision: 1.6
Committed: Thu Feb 8 03:09:32 2007 UTC (17 years, 3 months ago) by root
Branch: MAIN
Changes since 1.5: +5 -4 lines
Log Message:
Object => object

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 # Process the color/face info now
264 } elsif ($var eq "color_fg") {
265 $lfg = $values[0];
266 next line;
267 } elsif ($var eq "color_bg") {
268 $lbg = $values[0];
269 next line;
270 } elsif ($var eq "end") {
271 print ARCH "editor_folder $pathto\n" if $pathto ne "";
272 } elsif ($var eq "visibility") {
273 $lvis = $values[0];
274 next line;
275 } elsif ($var eq "magicmap") {
276 $mm = $values[0];
277 next line;
278 } elsif ($var eq "attacktype") {
279 $at = 0;
280 foreach $t ( @values ) {
281 if ( $t =~ /^\d+$/ ) {
282 $at |= $t;
283 } else {
284 if ( defined( $attacktype{ $t } ) ) {
285 $at |= $attacktype{ $t };
286 } else {
287 &warn($arch . " has invalid attacktype " . $t);
288 }
289 }
290 }
291 $_ = $var . ' ' . $at;
292 } elsif ($var eq "is_floor") {
293 $floor = $values[0];
294 # is_floor is also needed for archs, so let it pass
295 # through
296 } elsif ($var eq "no_pick") {
297 $nopick = $values[0];
298 } elsif ($var eq "walk_on") {
299 $walkon = $values[0];
300 } elsif ($var eq "face") {
301 $lface[$#lface++] = $values[0]
302 } elsif ($var eq "anim") {
303 if ($anim{$arch}) {
304 &warn("$arch is a duplicate animation name");
305 $anim{$arch}="";
306 }
307 while (<ARC>) {
308 chomp;
309 $var = $_;
310 last if ($var =~ "mina\s*");
311 if ($var =~ /facings \S+$/) { }
312 elsif (! $faces{$var}) {
313 &warn($arch." is missing face ".$var);
314 }
315 else {
316 $lface[$#lface++] = $var;
317 }
318 $anim{$arch} .= "$var\n";
319 }
320 print ARCH "animation $arch\n";
321 next line; # don't want the mina
322 } elsif ($var eq "face" && ! $faces{$values[0]}) {
323 &warn($arch." is missing face ".$values[0])
324 } elsif ($var eq "smoothface") {
325 if ($smoothing{$values[0]} && ($smoothing{$values[0]} ne $values[1])) {
326 &warn($arch." duplicate smoothface for ".$values[0].": ".$smoothing{$values[0]}." and ".$values[1]);
327 } elsif ( ($values[0] eq "") || ($values[1] eq "")) {
328 &warn ($arch." incomplete smoothface entry found: ".$values[0]." ".$values[1]);
329 } else {
330 $smoothing{$values[0]}=$values[1]
331 }
332 next line; #smoothface must be excluded from archetype file
333 }
334 print ARCH $_,"\n";
335 }
336 close(ARC);
337 }
338 }
339
340 sub pline {
341 local($face) = shift;
342 print BMAPS sprintf("%05d",$idx++)," ",$face,"\n";
343 }
344
345 sub opline {
346 local($face) = shift;
347 print BMAPS sprintf("\\%05d",$idx++),"\t",$face,"\n";
348 }
349
350 sub pheader {
351 print BMAPS "# This file is generated by $0, do not edit\n";
352 }
353
354 sub bmapsOut {
355 &pheader;
356 $idx = 0;
357 &pline("bug.x11");
358 foreach $face (sort(keys %faces)) {
359 &pline($face) if $face !~ /bug\.x11/;
360 }
361 }
362
363 sub pathsOut {
364 &pheader;
365 $idx = 0;
366 &opline($root."/system/bug.x11");
367 foreach $face (sort(keys %faces)) {
368 &opline($faces{$face}) if $faces{$face} !~ /bug\.x11/;
369 }
370 }
371
372 sub treasuresOut {
373 foreach $treasure (@treasure_files) {
374 open(TREAS, $treasure) || &die("cannot open ".$treasure);
375 while(<TREAS>) {
376 if (! /^\s*$/) {
377 print TREASURES $_;
378 }
379 }
380 close(FACE);
381 }
382 }
383
384 sub facesOut {
385 foreach $face (@face_files) {
386 open(FACE, $face) || &die("cannot open ".$face);
387 while(<FACE>) {
388 chop;
389 local ($var, @values) = split;
390 if ($var eq "face") {
391 $lface = $values[0];
392 $lfg = "";
393 $lbg = "";
394 $lvis = "";
395 $mm = "";
396 $floor = "";
397 }
398 elsif ($var eq "color_fg") {
399 $lfg = $values[0];
400 }
401 elsif ($var eq "color_bg") {
402 $lbg = $values[0];
403 }
404 elsif ($var eq "visibility") {
405 $lvis = $values[0];
406 }
407 elsif ($var eq "magicmap") {
408 $mm = $values[0];
409 }
410 elsif ($var eq "is_floor") {
411 $floor = $values[0];
412 }
413 elsif ($var eq "end") {
414 &storeFaceInfo($lface, $lfg, $lbg, $lvis, $mm, $floor);
415 }
416 elsif ($var eq "animation") {
417 $animation=$values[0];
418 if ($anim{$1}) {
419 &warn("$animation is a duplicate animation name");
420 $anim{$animation}="";
421 }
422 while (<FACE>) {
423 chomp;
424 $var = $_;
425 last if ($var =~ /^mina\s*$/);
426 if ($var !~ /^facings/ ) {
427 if (! $faces{$var}) {
428 &warn($arch." is missing face ".$var);
429 }
430 else {
431 $lface[$#lface++] = $var;
432 }
433 }
434 $anim{$animation} .= "$var\n";
435 }
436 next; # don't want the mina
437 }
438 }
439 close(FACE);
440 }
441 print FACES "# This file is generated by $0, do not edit\n";
442 foreach $face (sort(keys %faces)) {
443 if ($fg{$face} ne "" || $bg{$face} ne "" || $visibility{$face} ne "" ||
444 $magicmap{$face} ne "" || $floor{$face} ne "") {
445 print FACES "face ".$face."\n";
446 print FACES "color_fg ".$fg{$face}."\n"
447 if $fg{$face} ne "";
448 print FACES "color_bg ".$bg{$face}."\n"
449 if $bg{$face} ne "";
450 print FACES "visibility ".$visibility{$face}."\n"
451 if $visibility{$face} ne "";
452 print FACES "magicmap ".$magicmap{$face}."\n"
453 if $magicmap{$face} ne "";
454 print FACES "is_floor ".$floor{$face}."\n"
455 if $floor{$face} ne "";
456 print FACES "end\n";
457 }
458 }
459 }
460
461 sub animOut {
462 foreach $anim (sort keys %anim) {
463 print ANIM "anim $anim\n$anim{$anim}mina\n";
464 $animationsNum++;
465 }
466 }
467 sub smoothOut {
468 local ($sm);
469 print SMOOTHS "##########################################################\n";
470 print SMOOTHS "# Do not touch this file. #\n";
471 print SMOOTHS "# It has been generated from the information present #\n";
472 print SMOOTHS "# in the archetype files. #\n";
473 print SMOOTHS "# To add new entries, simply add #\n";
474 print SMOOTHS "# smoothface xxx yyy #\n";
475 print SMOOTHS "# to an archetype and collect.pl will put below an entry #\n";
476 print SMOOTHS "# xxx yyy #\n";
477 print SMOOTHS "##########################################################\n\n";
478 print SMOOTHS "# default smooth. Needed for fallbacking\n";
479 print SMOOTHS "default_smoothed.111 sdefault.001\n";
480 print SMOOTHS "\n# Data extracted from arch files\n";
481 foreach $sm (sort (keys %smoothing)) {
482 print SMOOTHS "$sm $smoothing{$sm}\n";
483 $smoothNum++;
484 }
485 }
486
487 ### print out statical information
488 sub stats {
489 &info(Archs.":\t".$archsNum);
490 &info(Images.":\t".$facesNum);
491 &info(Faces.":\t".$facesFileNum);
492 &info(Animations.":\t".$animationsNum);
493 &info(Treasures.":\t".($#treasure_files+1));
494 &info(Trash.":\t".$trashNum);
495 &info(Smooths.":\t".$smoothNum);
496 &info("Comment lines:\t".$commentNum);
497 }