6 # ent file managing tool
10 # perl entmerge.pl $scalefactor < mapname.map > mapname.ent
13 # perl entmerge.pl $scalefactor mapname.ent < mapname.map > mapname-merged.map
16 # perl bsptool.pl mapname.bsp -xentities > mapname.ent
19 # perl bsptool.pl mapname.bsp -rentities < mapname.ent
23 warn "Origin brushes not supported yet";
36 chomp; s/\r//g; s/\0//g; s/\/\/.*$//; s/^\s+//; s/\s+$//; next if /^$/;
43 chomp; s/\r//g; s/\0//g; s/\/\/.*$//; s/^\s+//; s/\s+$//; next if /^$/;
45 if(/^"(.*?)" "(.*)"$/)
53 push @brushes, $brush;
57 chomp; s/\r//g; s/\0//g; s/\/\/.*$//; s/^\s+//; s/\s+$//; next if /^$/;
66 chomp; s/\r//g; s/\0//g; s/\/\/.*$//; s/^\s+//; s/\s+$//; next if /^$/;
93 return \%ent, \@brushes;
99 die "Unexpected line in top level: >>$_<<";
106 sub UnparseEntity($$)
108 my ($ent, $brushes) = @_;
115 $s .= "\"$_\" \"$ent{$_}\"\n";
123 $s .= "$_\n" for @$_;
132 my ($scale, $in_ent) = @ARGV;
135 if not defined $scale;
139 my @entities_skipped = ();
141 # THIS part is always a .map file
146 my ($ent, $brushes) = ParseEntity \*STDIN;
151 if($first && $ent->{classname} eq 'worldspawn')
153 $keeplights = $ent->{_keeplights};
154 delete $ent->{_keeplights};
155 @submodels = ($brushes);
161 push @entities, { classname => "worldspawn" };
165 if($ent->{classname} eq 'worldspawn')
167 $ent->{classname} = "worldspawn_renamed";
170 if(grep { $_ eq $ent->{classname} } qw/group_info func_group misc_model _decal _skybox/)
172 push @entities_skipped, [$ent, $brushes];
176 if(!$keeplights && $ent->{classname} =~ /^light/)
178 push @entities_skipped, [$ent, $brushes];
185 push @submodels, $brushes;
186 $ent->{model} = sprintf "*%d", $i;
190 push @entities, $ent;
197 push @entities, { classname => "worldspawn" };
203 # translate map using ent to map
204 open my $fh, "<", $in_ent
205 or die "$in_ent: $!";
207 # THIS part is always an .ent file now
208 my @entities_entfile = ();
212 my ($ent, $brushes) = ParseEntity $fh;
217 if($first && $ent->{classname} eq 'worldspawn')
224 push @entities_entfile, { classname => "worldspawn" };
227 if($ent->{classname} eq 'worldspawn')
229 $ent->{classname} = "worldspawn_renamed";
233 push @entities_entfile, $ent;
240 push @entities_entfile, { classname => "worldspawn" };
244 for(@entities_entfile)
247 my $submodel = undef;
249 $e{gridsize} = "64 64 128" if not exists $e{gridsize};
250 $e{lip} /= $scale if exists $e{lip};
251 $e{origin} = join ' ', map { $_ / $scale } split /\s+/, $e{origin} if exists $e{origin};
252 $e{gridsize} = join ' ', map { $_ / $scale } split /\s+/, $e{gridsize} if exists $e{gridsize} and $first;
256 $submodel = $submodels[0];
260 elsif(defined $e{model} and $e{model} =~ /^\*(\d+)$/)
262 $submodel = $submodels[$1];
265 print UnparseEntity \%e, $submodel;
268 for(@entities_skipped)
270 print UnparseEntity $_->[0], $_->[1];
276 # translate map to ent
282 if(defined $e{model} and $e{model} =~ /^\*(\d+)$/)
284 my $org = BrushOrigin $submodels{$e{origin}};
289 $e{gridsize} = "64 64 128" if not exists $e{gridsize};
290 $e{lip} *= $scale if exists $e{lip};
291 $e{origin} = join ' ', map { $_ * $scale } split /\s+/, $e{origin} if exists $e{origin};
292 $e{gridsize} = join ' ', map { $_ * $scale } split /\s+/, $e{gridsize} if exists $e{gridsize} and $first;
294 print UnparseEntity \%e, undef;