#!/opt/bin/perl use strict; no utf8; use Crossfire::Map; use Storable; use POSIX; use File::Compare; use Gtk2 -init; my %type; my ($part_x, $part_y); if ($ARGV[0] eq 'pixel2map') { my ($x, $y) = ($ARGV[1], $ARGV[2]); $x = int ($x / 50); $y = int ($y / 50); $x += 100; $y += 100; print "gce $ENV{CROSSFIRE_LIBDIR}/maps/world/world_${x}_${y}\n"; exit } elsif ($ARGV[0] eq 'partial') { ($part_x, $part_y) = ($ARGV[1], $ARGV[2]); } elsif ($ARGV[0] =~ m/-*?he?l?p?/) { print <] possible modes are: - pixel2map takes 2 further arguments representing coordinates in world.png and returns the world map file where the coordinate points to. - partial takes 2 further arguments that should be X and Y coordinates of the worldmap (starting at 100/100 and ending at 129/129). it will only generate that particular worldmap. (no overlay png is generated in this mode) without any mode the complete world is regenerated from the world.png and the overlay png is written. USAGE exit } Crossfire::load_archetypes; chdir ".." unless -d "world-precomposed/."; -d "maps/world/." and -d "world-precomposed/." or die "need maps/world and world-precomposed in ."; my $PLT_FILE = "maps/world/gridmap.arch.plt"; my $WORLD_FILE = "maps/world/gridmap.arch.png"; my $MASK_FILE = "maps/world/gridmap.arch.mask.png"; { open my $plt, $PLT_FILE or die "Couldn't open $PLT_FILE: $!\n"; for (<$plt>) { my ($arch, $color) = split /\s+/; $type{$arch} = "#$color" if $arch =~ /\S/; } } open my $png, "convert $WORLD_FILE -depth 8 rgb:- |" or die "convert :$!"; 1500*1500*3 == read $png, my $world, 1500*1500*3 or die; my $mask; my $maskfh; unless (defined $part_x) { open my $mmaskfh, "| convert -depth 8 -size 1500x1500 rgba:- $MASK_FILE" or die "convert2: $!"; $maskfh = $mmaskfh; $mask = "\x00\x00\x00\x00" x (1500*1500); } my %color; my @pids; for my $k (keys %type) { my $v = join "", map chr, (map $_*255/15, map hex, split //, substr $type{$k}, 1); $color{$v} = $k; } for my $Y (100..129) { next if defined $part_y and $Y != $part_y; print "$Y\n";#d# for my $X (100..129) { next if defined $part_x and $X != $part_x; my $mapname = sprintf "world_%03d_%03d", $X, $Y; my $map = new_from_file Crossfire::Map "maps/world/$mapname.map" or die "maps/world/$mapname.map: $!"; { my $X = ($X - 100) * 50; my $Y = ($Y - 100) * 50; for my $y (0..49) { for my $x (0..49) { my $ofs = (($Y + $y)* 1500 + $X + $x); if (defined $mask) { substr $mask, $ofs * 4, 4, $map->{map}[$x][$y] ? "\xff\x00\x00\xff" : "\xff\xff\xff\x00"; } unless (grep $Crossfire::ARCH{$_->{_name}}{is_floor}, @{ $map->{map}[$x][$y] }) { my $type = substr $world, $ofs * 3, 3; if (my $k = $color{$type}) { unshift @{ $map->{map}[$x][$y] }, { _name => "$k", }; } else { die sprintf "colour '%s' not defined at %s+%s+%s", (unpack "H*", $type), $mapname, $x, $y, } } } } } if ((my $pid = fork)) { push @pids, $pid; waitpid shift @pids, 0 if @pids >= 3; } else { $map->write_file ("world-precomposed/$mapname.map~"); if (File::Compare::cmp "world-precomposed/$mapname.map", "world-precomposed/$mapname.map~") { print "replacing world-precomposed/$mapname.map\n"; rename "world-precomposed/$mapname.map~", "world-precomposed/$mapname.map"; } else { unlink "world-precomposed/$mapname.map~"; } warn $@ if $@; POSIX::_exit 0; } } } print $maskfh $mask if defined $mask; waitpid shift @pids, 0 if @pids >= 1; system "chmod -R u=rwX,go=rX world-precomposed"; system "rsync -avz world-precomposed/. ruth:/var/www/cfmaps.schmorp.de/world-precomposed/.";