1 | #!/opt/bin/perl |
1 | #!/opt/bin/perl |
2 | |
2 | |
3 | use strict; |
3 | use strict; |
|
|
4 | no utf8; |
4 | |
5 | |
5 | use Crossfire::Map; |
6 | use Crossfire::Map; |
6 | use Storable; |
7 | use Storable; |
7 | use POSIX; |
8 | use POSIX; |
8 | use File::Compare; |
9 | use File::Compare; |
9 | |
10 | |
10 | use Gtk2 -init; |
11 | use Gtk2 -init; |
11 | |
|
|
12 | Crossfire::load_archetypes; |
|
|
13 | |
|
|
14 | open my $png, "convert world.png -depth 8 rgb:- |" |
|
|
15 | or die "convert :$!"; |
|
|
16 | 1500*1500*3 == read $png, my $world, 1500*1500*3 or die; |
|
|
17 | |
|
|
18 | chdir ".." unless -d "maps/."; |
|
|
19 | -d "maps/world/." and -d "maps/world-overlay/." or die "need maps/world and maps/world-overlay in ."; |
|
|
20 | |
12 | |
21 | my %type = ( |
13 | my %type = ( |
22 | deep_sea => "#006", |
14 | deep_sea => "#006", |
23 | sea => "#008", |
15 | sea => "#008", |
24 | shallow_sea => "#00a", |
16 | shallow_sea => "#00a", |
… | |
… | |
38 | desert => "#cc0", |
30 | desert => "#cc0", |
39 | |
31 | |
40 | darkforest => "#040", |
32 | darkforest => "#040", |
41 | evergreens => "#0a0", |
33 | evergreens => "#0a0", |
42 | woods => "#080", |
34 | woods => "#080", |
43 | |
35 | |
44 | swamp => "#660", |
36 | swamp => "#660", |
45 | deep_swamp => "#440", |
37 | deep_swamp => "#440", |
46 | |
38 | |
47 | jungle_1 => "#084", |
39 | jungle_1 => "#084", |
48 | |
40 | |
49 | flagstone => "#bbb", |
41 | flagstone => "#bbb", |
50 | istone => "#bbc", |
42 | istone => "#bbc", |
51 | |
43 | |
… | |
… | |
63 | drifts => "#eef", |
55 | drifts => "#eef", |
64 | snow => "#eff", |
56 | snow => "#eff", |
65 | cobblestones => "#ea2", |
57 | cobblestones => "#ea2", |
66 | ); |
58 | ); |
67 | |
59 | |
|
|
60 | my ($part_x, $part_y); |
|
|
61 | |
|
|
62 | if ($ARGV[0] eq 'palette') { |
|
|
63 | mkdir "/tmp/$$.palette" |
|
|
64 | or die "Couldn't make /tmp/$$.palette"; |
|
|
65 | |
|
|
66 | for (keys %type) { |
|
|
67 | my $color = $type{$_}; |
|
|
68 | $color =~ s/^#//; |
|
|
69 | system ("convert -size 300x30 xc:\\#$color -pointsize 32 -fill \"red\" -gravity east -draw \"text 0,0 \\\"$_\\\"\" /tmp/$$.palette/$color.png"); |
|
|
70 | } |
|
|
71 | |
|
|
72 | system ("convert -append " |
|
|
73 | . join (' ', |
|
|
74 | map { |
|
|
75 | my $c = $_; $c =~ s/^#//; "/tmp/$$.palette/$c.png" |
|
|
76 | } sort values %type |
|
|
77 | ) |
|
|
78 | . " palette.png" |
|
|
79 | ); |
|
|
80 | |
|
|
81 | system ("rm -r /tmp/$$.palette"); |
|
|
82 | exit |
|
|
83 | |
|
|
84 | } elsif ($ARGV[0] eq 'pixel2map') { |
|
|
85 | my ($x, $y) = ($ARGV[1], $ARGV[2]); |
|
|
86 | $x = int ($x / 50); |
|
|
87 | $y = int ($y / 50); |
|
|
88 | $x += 100; |
|
|
89 | $y += 100; |
|
|
90 | print "gce $ENV{CROSSFIRE_LIBDIR}/maps/world/world_${x}_${y}\n"; |
|
|
91 | exit |
|
|
92 | } elsif ($ARGV[0] eq 'partial') { |
|
|
93 | ($part_x, $part_y) = ($ARGV[1], $ARGV[2]); |
|
|
94 | } elsif ($ARGV[0] =~ m/-*?:he?l?p?/) { |
|
|
95 | print <<USAGE; |
|
|
96 | gen_worldmap [<mode>] |
|
|
97 | possible modes are: |
|
|
98 | - palette generates the palette.png for drawing world.png |
|
|
99 | - pixel2map takes 2 further arguments representing coordinates in |
|
|
100 | world.png and returns the world map file where the coordinate |
|
|
101 | points to. |
|
|
102 | - partial takes 2 further arguments that should be X and Y coordinates |
|
|
103 | of the worldmap (starting at 100/100 and ending at 129/129). |
|
|
104 | it will only generate that particular worldmap. |
|
|
105 | (no overlay png is generated in this mode) |
|
|
106 | without any mode the complete world is regenerated from the world.png and |
|
|
107 | the overlay png is written. |
|
|
108 | USAGE |
|
|
109 | } |
|
|
110 | |
|
|
111 | Crossfire::load_archetypes; |
|
|
112 | |
|
|
113 | open my $png, "convert world.png -depth 8 rgb:- |" |
|
|
114 | or die "convert :$!"; |
|
|
115 | 1500*1500*3 == read $png, my $world, 1500*1500*3 or die; |
|
|
116 | |
|
|
117 | my $mask; |
|
|
118 | my $maskfh; |
|
|
119 | unless (defined $part_x) { |
|
|
120 | open \*maskfh, "| convert -depth 8 -size 1500x1500 rgba:- mask.png" |
|
|
121 | or die "convert2: $!"; |
|
|
122 | $mask = "\x00\x00\x00\x00" x (1500*1500); |
|
|
123 | } |
|
|
124 | |
|
|
125 | chdir ".." unless -d "maps/."; |
|
|
126 | -d "maps/world/." and -d "maps/world-overlay/." or die "need maps/world and maps/world-overlay in ."; |
|
|
127 | |
68 | my %color; |
128 | my %color; |
69 | my @pids; |
129 | my @pids; |
70 | |
130 | |
71 | for my $k (keys %type) { |
131 | for my $k (keys %type) { |
72 | my $v = join "", map chr, (map $_*255/15, map hex, split //, substr $type{$k}, 1); |
132 | my $v = join "", map chr, (map $_*255/15, map hex, split //, substr $type{$k}, 1); |
73 | $color{$v} = $k; |
133 | $color{$v} = $k; |
74 | } |
134 | } |
75 | |
135 | |
76 | for my $X (100..129) { |
136 | for my $Y (100..129) { |
|
|
137 | next if defined $part_y and $Y != $part_y; |
|
|
138 | |
77 | print "$X\n";#d# |
139 | print "$Y\n";#d# |
|
|
140 | |
78 | for my $Y (100..129) { |
141 | for my $X (100..129) { |
|
|
142 | next if defined $part_x and $X != $part_x; |
|
|
143 | |
79 | my $mapname = sprintf "world_%03d_%03d", $X, $Y; |
144 | my $mapname = sprintf "world_%03d_%03d", $X, $Y; |
80 | my $map = new_from_file Crossfire::Map "maps/world-overlay/$mapname" |
145 | my $map = new_from_file Crossfire::Map "maps/world-overlay/$mapname" |
81 | or die "maps/world-overlay/$mapname: $!"; |
146 | or die "maps/world-overlay/$mapname: $!"; |
82 | |
147 | |
83 | { |
148 | { |
84 | my $X = ($X - 100) * 50; |
149 | my $X = ($X - 100) * 50; |
85 | my $Y = ($Y - 100) * 50; |
150 | my $Y = ($Y - 100) * 50; |
86 | for my $x (0..49) { |
151 | for my $y (0..49) { |
87 | for my $y (0..49) { |
152 | for my $x (0..49) { |
88 | next if grep $Crossfire::ARCH{$_->{_name}}{is_floor}, @{ $map->{map}[$x][$y] }; |
153 | my $ofs = (($Y + $y)* 1500 + $X + $x); |
89 | |
154 | |
90 | my $ofs = (($Y + $y)* 1500 + $X + $x) * 3; |
155 | if (defined $mask) { |
|
|
156 | substr $mask, $ofs * 4, 4, |
|
|
157 | $map->{map}[$x][$y] ? "\xff\x00\x00\xff" : "\xff\xff\xff\x00"; |
91 | |
158 | } |
92 | my $type = substr $world, $ofs, 3; |
|
|
93 | |
159 | |
|
|
160 | unless (grep $Crossfire::ARCH{$_->{_name}}{is_floor}, @{ $map->{map}[$x][$y] }) { |
|
|
161 | |
|
|
162 | my $type = substr $world, $ofs * 3, 3; |
|
|
163 | |
94 | if (my $k = $color{$type}) { |
164 | if (my $k = $color{$type}) { |
95 | unshift @{ $map->{map}[$x][$y] }, { |
165 | unshift @{ $map->{map}[$x][$y] }, { |
96 | _name => "$k", |
166 | _name => "$k", |
97 | }; |
167 | }; |
98 | } else { |
168 | } else { |
99 | die sprintf "colour '%s' not defined at %s+%s+%s", |
169 | die sprintf "colour '%s' not defined at %s+%s+%s", |
100 | (unpack "H*", $type), $mapname, $x, $y, |
170 | (unpack "H*", $type), $mapname, $x, $y, |
|
|
171 | } |
101 | } |
172 | } |
102 | # delete $map->{map}[$x][$y]; |
|
|
103 | } |
173 | } |
104 | } |
174 | } |
105 | } |
175 | } |
106 | |
176 | |
107 | if ((my $pid = fork)) { |
177 | if ((my $pid = fork)) { |
… | |
… | |
119 | POSIX::_exit 0; |
189 | POSIX::_exit 0; |
120 | } |
190 | } |
121 | } |
191 | } |
122 | } |
192 | } |
123 | |
193 | |
124 | POSIX::_exit 0; |
194 | print $maskfh $mask if defined $mask; |
125 | |
195 | |
|
|
196 | waitpid shift @pids, 0 if @pids >= 1; |
|
|
197 | |