Merge branch 'master' of https://Governor-Tarkin@bitbucket.org/Governor-Tarkin/swg...
[swg-src.git] / tools / findAllCollideableObjects.pl
blob693c68433b2f89884e389dc06201bb726ab1bee5
1 #!/usr/bin/perl
3 use strict;
4 use warnings;
5 use perllib::Iff;
7 # Things to look for:
9 # object templates
10 # forceNoCollision
12 # appearance templtaes
13 # FORM 0003
14 # Extents
15 # NULL collision extent means not collideable
16 # 1163416400 - EXSP
17 # 1163412056 - EXBX
18 # 1480808780 - XCYL
19 # 1129140308 - CMPT
20 # 1146372428 - DTAL
21 # 1129141064 - CMSH
22 # 1314212940 - NULL
24 # Path:
25 # objectTemplate (probably have to go up heirarchy / shared)
26 # - scan for forceNoCollision
27 # - scan for appearanceTemplate (server side)
28 # appearanceTemplate
29 # - scan for ssa
30 # serverSideAppearance
31 # - scan for collision extent
33 use constant DEBUG => 1;
35 use constant UNTESTED => -1;
36 use constant NOT_COLLIDEABLE => 0;
37 use constant COLLIDEABLE => 1;
39 sub usage
41 die "\n\tfindAllCollideableObjects.pl <branch>\n\n";
44 usage if (!@ARGV);
46 my $branch = shift;
48 my $branchDir = "";
49 open (P4, "p4 -ztag where //depot/swg/$branch/... |") || die "Can't run p4 where for $branch\n";
50 while (<P4>)
52 $branchDir = $1 if (m!\.\.\. path (\S+)[\\\/]\.\.\.!);
54 close (P4);
56 $branchDir =~ s![\\\/]+!/!g;
58 my %appearanceTemplates;
59 my %objectTemplates;
61 print "\nBuilding list of all object templates...\n";
62 open (P4, "p4 files //depot/swg/$branch/dsrc/*/sys.s*/compiled/game/object/... |") || die "Can't run p4 files for $branch\n";
63 while (<P4>)
65 next if (/ - delete/);
67 chomp;
68 s!\#.*$!!;
70 # element maps to : [ <absolute path>, <collideable> ]
71 my $path = $_;
72 $path =~ s!//depot/swg/$branch/!$branchDir/!;
73 $_ =~ s!^.*/dsrc/sku[^\\\/]+/sys[^\\\/]+/compiled/game/!!;
75 $objectTemplates{$_} = [$path, UNTESTED];
77 close (P4);
79 print "\nBuilding list of all appearance files...\n";
80 open (P4, "p4 files //depot/swg/$branch/data/*/sys.*/.../appearance/... |") || die "Can't run p4 files for $branch\n";
81 while (<P4>)
83 next if (/ - delete/);
85 chomp;
86 s!\#.*$!!;
88 my $path = $_;
89 $path =~ s!//depot/swg/$branch/!$branchDir/!;
90 $_ =~ s!^.*/data/sku[^\\\/]+/sys[^\\\/]+/[^\\\/]+/[^\\\/]+/!!;
92 $appearanceTemplates{$_} = [$path, UNTESTED];
94 close (P4);
96 print "\nScanning all object templates...\n";
97 foreach my $objectTemplate (sort keys %objectTemplates)
99 # skip this element if we've tested it
100 next if ($objectTemplates{$objectTemplate}->[1] != UNTESTED);
102 if ($objectTemplate =~ m!/base/! || $objectTemplate =~ m!/base/!)
104 print "$objectTemplate : not collideable : because it's a base object\n" if (DEBUG);
105 $objectTemplates{$objectTemplate}->[1] = NOT_COLLIDEABLE;
106 next;
109 if ($objectTemplate =~ m!\.(btm)|(me)|(txt)!)
111 print "$objectTemplate : not collideable : because it's a file I don't care about\n" if (DEBUG);
112 $objectTemplates{$objectTemplate}->[1] = NOT_COLLIDEABLE;
113 next;
116 my $collideable = UNTESTED;
117 my $analyzingObjectTemplate = $objectTemplate;
118 my $debugTabs = "";
120 while ($collideable == UNTESTED)
122 my $forceNoCollision = 0;
123 my $appearanceTemplate = "";
124 my $baseObjectTemplate = "";
125 my $sharedObjectTemplate = "";
126 my $portalLayoutFile = "";
128 if (DEBUG)
130 print "${debugTabs}Scanning $analyzingObjectTemplate...\n";
131 $debugTabs .= "\t";
134 my $analyzingObjectTemplateDisk = $objectTemplates{$analyzingObjectTemplate}->[0];
135 open (OT, $analyzingObjectTemplateDisk) || die "Can't open $analyzingObjectTemplateDisk\n";
136 while (<OT>)
138 $baseObjectTemplate = $1 if (m/^\s*\@base\s+(\S+)/i);
139 $forceNoCollision = 1 if (m/^\s*forceNoCollision\s*=\s*true/i);
140 $appearanceTemplate = $1 if (m/^\s*appearanceFilename\s*=\s*\"(\S+)\"/i);
141 $sharedObjectTemplate = $1 if (m/^\s*(?:crafted)?sharedTemplate\s*=\s*\"(\S+)\"/i);
142 $portalLayoutFile = $1 if (m/^\s*portalLayoutFilename\s*=\s*\"(\S+)\"/i);
144 close (OT);
146 if ($forceNoCollision)
148 print "$objectTemplate : not collideable : forceNoCollision specified\n" if (DEBUG);
149 $collideable = NOT_COLLIDEABLE;
150 last;
153 if ($portalLayoutFile)
155 print "$objectTemplate : collideable : portal layout found\n" if (DEBUG);
156 $collideable = COLLIDEABLE;
157 last;
160 if ($appearanceTemplate)
162 my $appearanceTemplateDisk = (exists $appearanceTemplates{$appearanceTemplate}) ? $appearanceTemplates{$appearanceTemplate}->[0] : "";
164 if ($appearanceTemplateDisk =~ m!/sys\.client/!)
166 print "$objectTemplate : not collideable : appearance is client side only\n" if (DEBUG);
167 $collideable = NOT_COLLIDEABLE;
168 last;
170 else
172 print "${debugTabs}Scanning appearance $appearanceTemplate...\n" if (DEBUG);
173 if ($appearanceTemplateDisk)
175 my $appearanceFileHandle;
176 open ($appearanceFileHandle, $appearanceTemplateDisk) || die "Can't open $appearanceTemplateDisk\n";
177 my $iff = Iff->createFromFileHandle($appearanceFileHandle);
178 close ($appearanceFileHandle);
180 # Handle Iff contents.
181 my $name = $iff->getCurrentName();
182 if ($name eq "APT " && $iff->isCurrentForm())
184 $iff->enterForm();
186 $name = $iff->getCurrentName();
187 if ($name eq "0000" && $iff->isCurrentForm())
189 $iff->enterForm();
191 $name = $iff->getCurrentName();
193 if ($name eq "NAME" && !$iff->isCurrentForm())
195 $iff->enterChunk();
197 my $ssaFileName = $iff->read_string();
198 print "${debugTabs}Scanning ssa $ssaFileName...\n" if (DEBUG);
199 my $ssaFileNameDisk = (exists $appearanceTemplates{$ssaFileName}) ? $appearanceTemplates{$ssaFileName}->[0] : "";
200 if ($ssaFileNameDisk)
202 my $ssaFileHandle;
203 open ($ssaFileHandle, $ssaFileNameDisk) || die "Can't open $ssaFileNameDisk\n";
204 $iff = Iff->createFromFileHandle($ssaFileHandle);
205 close ($ssaFileHandle);
207 # Handle Iff contents
208 my $name = $iff->getCurrentName();
209 if ($name eq "APPR" && $iff->isCurrentForm())
211 $iff->enterForm();
213 $name = $iff->getCurrentName();
214 if ($name eq "0003" && $iff->isCurrentForm())
216 $iff->enterForm();
218 # enter / exit past extent block
219 $iff->enterForm();
220 $iff->exitForm();
222 # we should now be pointing to the collision property form
223 $name = $iff->getCurrentName();
225 if ($name eq "NULL")
227 # enter / exit past collision property block
228 $iff->enterForm();
229 $iff->exitForm();
231 # enter / exit past hardpoint block
232 $iff->enterForm();
233 $iff->exitForm();
235 $name = $iff->getCurrentName();
237 if ($name eq "FLOR" && $iff->isCurrentForm())
239 $iff->enterForm();
241 $name = $iff->getCurrentName();
242 if ($name eq "DATA" && !$iff->isCurrentForm())
244 $iff->enterChunk();
246 my $hasFloor = $iff->read_uint8();
248 if ($hasFloor == 0)
250 print "$objectTemplate : not collideable : null collision property and null floor\n" if (DEBUG);
251 $collideable = NOT_COLLIDEABLE;
253 else
255 print "$objectTemplate : collideable : non-null floor\n" if (DEBUG);
256 $collideable = COLLIDEABLE;
261 else
263 print "$objectTemplate : collideable : non-null collision property\n" if (DEBUG);
264 $collideable = COLLIDEABLE;
267 else
269 # for all other forms of this piece of data, we assume not collideable
270 print "$objectTemplate : not collideable : null collision property\n" if (DEBUG);
271 $collideable = NOT_COLLIDEABLE;
279 # if we got here and didn't get a solution, default to collideable
280 if ($collideable == UNTESTED)
282 print "$objectTemplate : collideable : couldn't get appearance template info\n" if (DEBUG);
283 $collideable = COLLIDEABLE;
284 last;
290 $sharedObjectTemplate =~ s!\.iff!\.tpf!;
291 $baseObjectTemplate =~ s!\.iff!\.tpf!;
293 if (!$sharedObjectTemplate || !exists $objectTemplates{$sharedObjectTemplate})
295 if (!$baseObjectTemplate || !exists $objectTemplates{$baseObjectTemplate})
297 print "$objectTemplate : collideable : no base, no shared, no appearance specified, defaulting\n" if (DEBUG);
298 $collideable = COLLIDEABLE;
299 last;
301 else
303 $sharedObjectTemplate = "";
307 $analyzingObjectTemplate = ($sharedObjectTemplate) ? $sharedObjectTemplate : $baseObjectTemplate;
310 $objectTemplates{$objectTemplate}->[1] = $collideable;
313 print "\nPrinting out object templates with collision...\n";
314 foreach my $template (sort keys %objectTemplates)
316 print "$template\n" if ($objectTemplates{$template}->[1] == COLLIDEABLE && $template !~ /shared_/);