Kategorien
FreewarWiki:Bot/Skripts/makemap.php
Zur Navigation springen
Zur Suche springen
Letzte Änderungen:
- Umstellung auf "getopt" (Angabe von Optionen auf der Befehlszeile). Neue Features "Atlas" und "Einzelkarten", damit auch Erstellung von Dungeon-Karten. Damit kann man jetzt weitgehend automatisch sowas machen wie http://www.remote-island.org/101912/atlas.pdf (Quelltext: http://www.remote-island.org/101912/atlas.odt) --Count Ypsilon (Diskussion) 23:24, 17. Feb. 2019 (CET)
<?php
header('Content-Type: text/plain; charset=utf-8;');
const BERGFELD = 'http://welt1.freewar.de/freewar/images/map/std.jpg';
const ATLAS_TEMPLATE = 'atlas-vorlage.odt';
const GESAMTKARTE_LORU = array(2, 2, 170, 400);
const MAPLIST = 'maplist.txt';
const MAPCACHE = './map_cache';
/* ----------------------------------------------------------------------------
* Der Freewar-Kartengenerator
*
*
*/
function show_help() {
echo <<<EOF
Befehlszeilenoptionen:
--mode "gesamt": erzeugt eine Gesamtkarte für die Oberfläche
"einzel": erzeugt einzelne Karten für jedes Gebiet
"atlas": erzeugt ein Atlas-Dokument (OpenOffice/Libre-
Office-Format); benötigt dafür eine Vorlage
--dungeons auch Dungeons mit ausgeben
--grid alle X Zeilen/Spalten eine Linie
--cellspacing Pixel Abstand zwischen Feldern
--gridlabels Gitternetz mit Koordinaten beschriften
--rotatelabels Koordinaten an X-Achse rotieren
--gebietlabel Gebiete beschriften (bei Einzel/Atlas)
--labelfont TTF-Datei für Beschriftungen
--lighten nichtbetretbare/gebietsfremde Felder aufhellen
--output Name der Ausgabedatei/des Ausgabeverzeichnisses
--bgcolor Bildhintergrund in Hex
--verbose mehr Meldungen anzeigen
Bei Modus "Atlas" zusätzlich
--dpi Auflösung für die Bildausgabe (Default 140, größere Auflösung
bringt kleinere Bilder)
--pagewidth druckbare Seitenbreite in cm
--pageheight druckbare Seitenhöhe in cm
EOF;
}
// --- Einlesen der Befehlszeile ----------------------------------------------
$longopts = array(
"mode:", // gesamt (Default), einzel oder atlas
"dungeons", // sollen Dungeons mit ausgegeben werden?
"verbose", // soll das Programm geschwätzig sein?
"lighten", // sollen gebietsfremde Felde aufgehellt werden?
"bgcolor:", // Kartenhintergrund in Web-Notation (Default weiss)
"grid:", // Gitternetz-Abstand (Default keins)
"help", // Hilfe anzeigen
"gridlabels", // soll das Gitternetz beschriftet sein? (Default nein)
"gebietlabel", // soll die Gebietskarte ein Label haben? (Default nein)
"labelfont:", // TTF-Datei für die Beschriftungen
"rotatelabels", // soll X-Achesen-Label 90° rotiert sein? (Default nein)
"cellspacing:", // Feld-Abstand (Default 0)
"dpi:", // dpi für Bilder im Atlas (Default 140)
"pagewidth:", // druckbare Seitenbreite (cm, Papier-Rand) im Atlas
"pageheight:", // druckbare Seitenhöhe (cm, Papier-Rand) im Atlas
"output:", // Ausgabedatei oder -Verzeichnis
);
$o = getopt(NULL, $longopts, $optind);
$o['verbose'] = array_key_exists('verbose', $o);
if (array_key_exists('help', $o)) {
show_help();
exit;
}
if (!array_key_exists('mode', $o)) {
$o['mode'] = 'gesamt';
echo "Betriebsmodus \"Gesamtkarte\" automatisch gewählt. Programm mit --help\n";
echo "aufrufen für weitere Funktionen\n";
}
if ($o['mode'] != 'gesamt' && $o['mode'] != 'atlas' && $o['mode'] != 'einzel') {
echo "mode muss entweder 'atlas', 'einzel' oder 'gesamt' sein\n";
show_help();
exit;
}
if (!array_key_exists('bgcolor', $o)) {
$o['bgcolor'] = 'ffffff';
}
if (!preg_match('/^[a-f0-9]{6}$/i', $o['bgcolor'])) {
echo "bgcolor muss eine 6stellige Hexadezimalzahl sein, z.B. fafefa - nicht '".$o['bgcolor']."'\n";
show_help();
exit;
}
if (!array_key_exists('grid', $o)) {
$o['grid'] = 0;
}
if (!preg_match('/^\d\d?$/', $o['grid'])) {
echo "grid muss zwischen 0 und 99 liegen\n";
show_help();
exit;
}
$o['gridlabels'] = array_key_exists('gridlabels', $o);
if ($o['gridlabels'] && !$o['grid']) {
echo "gridlabels kann nur zusammen mit grid verwendet werden\n";
show_help();
exit;
}
$o['rotatelabels'] = array_key_exists('rotatelabels', $o);
if ($o['rotatelabels'] && !$o['gridlabels']) {
echo "rotatelabels kann nur zusammen mit gridlabels verwendet werden\n";
show_help();
exit;
}
$o['dungeons'] = array_key_exists('dungeons', $o);
$o['gebietlabel'] = array_key_exists('gebietlabel', $o);
if ($o['gebietlabel'] && $o['mode'] == 'gesamt') {
echo "--gebietlabel geht nur bei --mode atlas oder --mode einzel\n";
show_help();
exit;
}
$o['lighten'] = array_key_exists('lighten', $o);
if ($o['lighten'] && $o['mode'] == 'gesamt') {
echo "--lighten geht nur bei --mode atlas oder --mode einzel\n";
show_help();
exit;
}
if (!array_key_exists('cellspacing', $o)) $o['cellspacing'] = 0;
if (!preg_match('/^\d\d?$/', $o['cellspacing'])) {
echo "cellspacing muss zwischen 0 und 99 liegen\n";
show_help();
exit;
}
if ($o['mode'] == 'atlas') {
if (!array_key_exists('dpi', $o)) {
$o['dpi'] = 140;
}
if (!preg_match('/^\d\d\d?$/', $o['dpi'])) {
echo "dpi muss zwischen 10 und 999 liegen\n";
show_help();
exit;
}
if (!array_key_exists('pagewidth', $o)) $o['pagewidth'] = 12.85;
$o['pagewidth'] = strtr($o['pagewidth'], ",", ".");
if (!array_key_exists('pageheight', $o)) $o['pageheight'] = 19;
$o['pageheight'] = strtr($o['pageheight'], ",", ".");
if (!preg_match('/^\d\d?(\.\d+)?$/', $o['pageheight'])) {
echo "pageheight muss zwischen 0 und 99.9 liegen\n";
show_help();
exit;
}
if (!preg_match('/^\d\d?(\.\d+)?$/', $o['pagewidth'])) {
echo "pagewidth muss zwischen 0 und 99.9 liegen\n";
show_help();
exit;
}
} else {
if (array_key_exists('dpi', $o) ||
array_key_exists('pageheight', $o) ||
array_key_exists('pagewidth', $o)) {
echo "--dpi, --pageheight, --pagewidth gehen nur mit --mode atlas\n";
show_help();
exit;
}
}
if (!array_key_exists("labelfont", $o)) {
$o['labelfont'] = '/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf';
}
if ($o['gebietlabel'] || $o['gridlabels']) {
if (!file_exists($o['labelfont'])) {
echo "Datei ".$o['labelfont']." (--labelfont) nicht gefunden\n";
show_help();
exit;
}
}
if (!array_key_exists("output", $o)) {
$o['output'] = './karten';
if ($o['mode'] == 'atlas') $o['output'] = './atlas.odt';
if ($o['mode'] == 'gesamt' && !$o['dungeons']) $o['output'] = './Gesamtkarte (automatisch generiert).jpg';
}
if ($optind < $argc) {
echo "Ungültige Befehlszeilenoption\n";
show_help();
exit;
}
// --- Einlesen der Befehlszeile beendet --------------------------------------
if ($o['mode'] == 'atlas') {
// Atlas benötigt eine vorbereitete OpenOffice-Datei
if (!file_exists(ATLAS_TEMPLATE)) {
echo "Datei ".ATLAS_TEMPLATE." wird für --mode atlas benötigt, fehlt aber.\n";
echo "Entweder eine leere OpenOffice-Datei erzeugen, die irgendwo den Text\n";
echo "ADD CONTENT HERE enthält, oder herunterladen von\n";
echo "http://www.remote-island.org/101912/atlas-vorlage.odt";
exit;
}
if ($o['verbose']) echo ATLAS_TEMPLATE.' nach '.$o['output']." kopieren...\n";
copy(ATLAS_TEMPLATE, $o['output']);
$zipfile = new ZipArchive;
$res = $zipfile->open($o['output']);
if (!$res) {
echo "Fehler beim Öffnen der Datei ".$o['output']."!\n";
exit;
}
} else if ($o['mode'] != 'gesamt' || $o['dungeons']) {
mkdir($o['output'], 0777, TRUE);
if (!is_dir($o['output'])) {
echo "'".$o['output']."' ist kein Verzeichnis bzw. kann nicht angelegt werden!\n";
exit;
}
}
$count = 10000;
// ab hier nichts ändern ohne Kenntnisse über Funktionsweise des Skripts
// cacht mapfile
function cache_mapfile($url) {
$cache_file = MAPCACHE . "/". md5($url);
if (!file_exists($cache_file)) {
file_put_contents($cache_file, file_get_contents($url));
}
return $cache_file;
}
// trennzeichen für positionsschlüssel
$pos_delimiter = '|';
// Bergfeld cachen
cache_mapfile(BERGFELD);
// maplist holen
if ($o['verbose']) echo "Felder aus ".MAPLIST." holen und Bilder laden...\n";
$handle = fopen(MAPLIST, "r");
if (!$handle) {
echo "Kann Feldliste aus ".MAPLIST." nicht laden\n";
exit;
}
$field_rows = array();
while ($data = fgetcsv($handle, 1000, ";")) {
array_push($field_rows, $data);
}
fclose($handle);
// felder in `position` => `url` format überführen
$fields = [];
foreach ($field_rows as $field) {
$x = array_key_exists(2, $field) ? $field[2] : NULL;
$y = array_key_exists(3, $field) ? $field[3] : NULL;
$g = array_key_exists(0, $field) ? $field[0] : NULL;
$b = array_key_exists(1, $field) ? $field[1] : NULL;
if ($o["mode"] == "gesamt") {
// Für die Gesamtkarte werden die Felder des Kontinents als ein Gebiet
// behandelt
if ($x>GESAMTKARTE_LORU[0] && $y>GESAMTKARTE_LORU[1] &&
$x<GESAMTKARTE_LORU[2] && $y<GESAMTKARTE_LORU[3]) {
$g="Oberfläche";
} else {
// Dungeons (und Außenbereiche des Kontinents wie Narubia)
// nur, wenn --dungeons gesetzt ist
if (!$o['dungeons']) continue;
}
} else {
// Für Einzelkarten und Atlas kann man mit $dungeons steuern,
// ob auch Dungeons ausgegeben werden sollen
if (!$o['dungeons'] && $x<2) continue;
}
$lim = &$gebiet_limits[$g];
if (!$lim) {
$lim["minx"] = 99999;
$lim["miny"] = 99999;
$lim["maxx"] = -99999;
$lim["maxy"] = -99999;
}
// Hier wird die Größe jedes Gebiets ermittelt; dazu berücksichtigen
// wir aber nur die begehbaren Teile, sonst haben Karten wie z.B.
// Düsterfrostinsel einen unnötig großen Platzbedarf. TODO, dies
// konfigurierbar machen
if ($b) {
if ($x < $lim["minx"]) $lim["minx"] = $x;
if ($y < $lim["miny"]) $lim["miny"] = $y;
if ($x > $lim["maxx"]) $lim["maxx"] = $x;
if ($y > $lim["maxy"]) $lim["maxy"] = $y;
}
// und gleich bilddatein holen
$cache_file = cache_mapfile(array_key_exists(5, $field) ? $field[5] : NULL);
// kein Feldtitel oder `Feldtitel Pensal (brennend)`
if (!isset($g) || strpos($g, ' (brennend)') === false) {
$fields["{$x}$pos_delimiter{$y}"] = [
'x' => $x,
'y' => $y,
'g' => $g,
'begehbar' => $b,
'file' => $cache_file
];
}
}
// Randfelder einfügen
foreach ($fields as $field) {
// Randfelder
for ($diff_x = -1; $diff_x <= 1; ++$diff_x) {
for ($diff_y = -1; $diff_y <= 1; ++$diff_y) {
$edge = ($field['x'] + $diff_x) . $pos_delimiter . ($field['y'] + $diff_y);
if (!isset($fields[$edge])) {
$fields[$edge] = [
'x' => $field['x'] + $diff_x,
'y' => $field['y'] + $diff_y,
'file' => MAPCACHE . '/' . md5(BERGFELD)
];
}
}
}
}
# Groesse eines Kartenfelds feststellen
list($tilewidth, $tileheight) = getimagesize($cache_file);
if ($o['verbose']) echo "tile size: $tilewidth x $tileheight\n";
// ein weisses Kartenfeld herstellen
if ($o['lighten']) {
$aufheller = imagecreatetruecolor($tilewidth, $tileheight);
$farbe = imagecolorallocate($aufheller, 255, 255, 255);
imagefilledrectangle($aufheller, 0, 0, $tilewidth, $tileheight, $farbe);
}
if ($o["mode"] == 'atlas')
{
file_put_contents("odt/content.xml", file_get_contents("head.xml"));
$dungeons = "";
$oberflaeche = "";
}
foreach($gebiet_limits as $gebiet => $limits) {
// Bereich ermitteln
$max_x_found = $limits['maxx'] + 1;
$max_y_found = $limits['maxy'] + 1;
$min_x_found = $limits['minx'] - 1;
$min_y_found = $limits['miny'] - 1;
// Leeres Kartenbild erstellen
$mapwidth = ($max_x_found - $min_x_found + ($o['grid'] ? 3 : 1)) * $tilewidth +
($max_x_found - $min_x_found + 2) * $o['cellspacing'];
$mapheight = ($max_y_found - $min_y_found + ($o['grid'] ? 3 : 1)) * $tileheight +
($max_y_found - $min_y_found + 2) * $o['cellspacing'];
if ($o['verbose']) {
echo "Karte für '$gebiet': x_min: $min_x_found; x_max: $max_x_found; y_min: $min_y_found; y_max: $max_y_found; ";
echo "Bildgröße: $mapwidth x $mapheight\n";
}
$mapimage = imagecreatetruecolor($mapwidth, $mapheight);
if (!$mapimage) {
echo "Fehler bei der Erstellung des Kartenbilds für '$gebiet'\n";
continue;
}
// Hintergrundfarbe setzen
$bgarray = sscanf($o['bgcolor'], "%02X%02X%02X");
$bgindex = imagecolorallocate($mapimage, $bgarray[0], $bgarray[1], $bgarray[2]);
imagefill($mapimage, 0, 0, $bgindex);
// Gitternetz einzeichnen und ggf. beschriften
if ($o['grid']) {
for ($x = $min_x_found; $x <= $max_x_found; $x++) {
if ($x%$o['grid'] == 0) {
$mpx = ($x - $min_x_found + 1) * ($tilewidth + $o['cellspacing']) + $o['cellspacing'] + $tilewidth/2;
imageline($mapimage, $mpx, $o['rotatelabels'] ? 0 : 40, $mpx, $o['rotatelabels'] ? $mapheight : $mapheight - 40, 0);
if (!$o['gridlabels']) continue;
$t = $x;
if (strlen($t) > 4) $t=substr($t,0,2)."\n".substr($t,3);
// X-Achsen-Labels können entweder gerade stehen oder
// entlang der Achse (rotatelabels)
if ($o['rotatelabels']) {
imagettftext($mapimage, 11, 270, $mpx + 3, 5, 0, $o['labelfont'], $t);
$ar = imagettfbbox (11, 270, $o['labelfont'], $t);
imagettftext($mapimage, 11, 270, $mpx + 3, $mapheight - $ar[3] - 5, 0, $o['labelfont'], $t);
} else {
$ar = imagettfbbox (11, 0, $o['labelfont'], $t);
imagettftext($mapimage, 11, 0, $mpx + 3 - $ar[4]/2, 22 - $ar[5], 0, $o['labelfont'], $t);
imagettftext($mapimage, 11, 0, $mpx + 3 - $ar[4]/2, $mapheight + $ar[5] - 10, 0, $o['labelfont'], $t);
}
}
}
for ($y = $min_y_found; $y <= $max_y_found; $y++) {
if ($y%$o['grid'] == 0) {
$mpy = ($y - $min_y_found + 1) * ($tileheight + $o['cellspacing']) + $o['cellspacing'] + $tileheight/2;
imageline($mapimage, 0, $mpy, $mapwidth, $mpy, 0);
if (!$o['gridlabels']) continue;
$t = $y;
if (strlen($t) > 4) $t=substr($t,0,2)."\n".substr($t,3);
imagettftext($mapimage, 11, 0, 5, $mpy - 2, 0, $o['labelfont'], $t);
$ar = imagettfbbox (11, 0, $o['labelfont'], $t);
imagettftext($mapimage, 11, 0, $mapwidth - 5 - $ar[4], $mpy - 2, 0, $o['labelfont'], $t);
}
}
}
// Label für Gebiet einzeichnen; schwarze Box, darin weisse Box,
// darin Text
if ($o['gebietlabel']) {
$ar = imagettfbbox (16, 0, $o['labelfont'], $gebiet);
// FIXME die Zahlen hier sind etwas magisch durch Ausprobieren
// gewählt
imagefilledrectangle($mapimage, $mapwidth - $ar[4] - 55,
$mapheight + $ar[7] - 26, $mapwidth-51, $mapheight-21, 0);
imagefilledrectangle($mapimage, $mapwidth - $ar[4] - 54,
$mapheight + $ar[7] - 25, $mapwidth-52, $mapheight-22, $bgindex);
imagettftext($mapimage, 16, 0, $mapwidth - $ar[4] - 52,
$mapheight + $ar[7] - 7, 0, $o['labelfont'], $gebiet);
}
// Feldbilder an die richtige Stelle im Gebiet einzeichnen.
// Diese Schleife geht alle Felder durch, die im Rechteck liegen, das
// das Gebiet umgibt.
foreach ($fields as $key => $data) {
// weiter, wenn das Feld ausserhalb ist
if ($data['x'] < $min_x_found) continue;
if ($data['x'] > $max_x_found) continue;
if ($data['y'] < $min_y_found) continue;
if ($data['y'] > $max_y_found) continue;
// Feld kopieren
$offset = ($o['grid']) ? 1 : 0;
imagecopy($mapimage,
imagecreatefromjpeg($data['file']),
($data['x'] - $min_x_found + $offset) *
($tilewidth + $o['cellspacing']) + $o['cellspacing'],
($data['y'] - $min_y_found + $offset) *
($tileheight + $o['cellspacing']) + $o['cellspacing'],
0, 0,
$tilewidth, $tileheight);
// Feld aufhellen, wenn es nicht zum Gebiet gehört
if ($o['lighten'] && (!array_key_exists('begehbar', $data) || !$data['begehbar'] || $gebiet != $data['g'])) {
imagecopymerge($mapimage,
$aufheller,
($data['x'] - $min_x_found + $offset) *
($tilewidth + $o['cellspacing']) + $o['cellspacing'],
($data['y'] - $min_y_found + $offset) *
($tileheight + $o['cellspacing']) + $o['cellspacing'],
0, 0,
$tilewidth, $tileheight,
50);
}
}
// Ausgabe des Bildes für ein Gebiet. Im Gesamtkartenmodus gibt es nur
// ein Gebiet, also auch nur eine Ausgabe; in den anderen Modi passiert
// das hier öfter.
if ($o["mode"] == 'atlas') {
// Für die Atlas-Ausgabe werden Bilder, die nicht auf die Seite
// passen, eventuell gedreht oder zweigeteilt oder beides. Mehr
// ist aber nicht drin - wenn das Bild auch gedreht und zweigeteilt
// nicht passt, fliegt es raus.
$px_per_cm = $o['dpi'] / 2.54;
// Bildgröße in cm
$w = $mapwidth / $px_per_cm;
$h = $mapheight / $px_per_cm;
// Bild-Pixel-Spalte, an der wir durchschneiden, wenn nötig
// (wird gerundet auf ganze Felder, damit wir nicht mitten in
// einem Feld schneiden)
$cutoff = floor($o['pagewidth'] * $px_per_cm / ($tilewidth + $o['cellspacing']))
* ($tilewidth + $o['cellspacing']) - $o['cellspacing']/2 + 2;
// Leeres Array initialisieren; eventuell haben wir mehr als
// ein Ausgabebild
$images = array();
if ($w <= $o['pagewidth'] && $h <= $o['pageheight']) {
// alles super, Bild passt auf Seite
array_push($images, $mapimage);
} elseif ($h <= $o['pagewidth'] && $w <= $o['pageheight']) {
// Bild passt, wenn wir es drehen
array_push($images, imagerotate($mapimage, 90, $bgindex));
imagedestroy($mapimage);
} elseif ($w <= 2* $o['pagewidth'] && $h <= $o['pageheight']) {
// Bild passt, wenn wir es durchschneiden - also schneiden
// und zwei Teile in Ausgabe-Array stecken
// TODO: Formel 2*pagewidth nicht ganz korrekt, da cutoff
// bedeutet, dass wir die Seite nicht 100% ausnutzen
array_push($images, imagecrop($mapimage,
[ 'x' => 0, 'y' => 0, 'height' => $mapheight, 'width' => $cutoff ]));
array_push($images, imagecrop($mapimage,
[ 'x' => $cutoff, 'y' => 0, 'height' => $mapheight,
'width' => $mapwidth - $cutoff]));
imagedestroy($mapimage);
} elseif ($w <= $o['pageheight'] && $h <= 2 * $o['pagewidth']) {
// Bild passt rotiert und geschnitten
$m = imagerotate($mapimage, 90, $bgindex);
imagedestroy($mapimage);
$mapimage = $m;
$temp = $w; $w = $h; $h = $temp;
array_push($images, imagecrop($m, [ 'x' => 0, 'y' => 0,
'height' => $mapwidth, 'width' => $cutoff ]));
array_push($images, imagecrop($m, [ 'x' => $cutoff, 'y' => 0,
'height' => $mapwidth, 'width' => $mapheight - $cutoff]));
imagedestroy($m);
} else {
echo "Bild für '$gebiet' zu groß. Wähle höhere DPI oder größeres Papier\n";
}
// Wir führen zwei Ausgabedokumente, eins mit den oberirdischen
// Gebieten und eins mit den Dungeons:
if ($min_x_found < 0) {
$xml = & $dungeons;
} else {
$xml = & $oberflaeche;
}
// OpenOffice-XML an das passende Dokument anfügen
$xml .= '<text:h text:style-name="Heading_20_2" text:outline-level="2">'.
$gebiet."</text:h>";
foreach ($images as $image) {
$count++;
// TODO: Dieser Dateiname muss eigentlich eine Prüfsumme des Inhalts
// sein. Ist er es nicht, meldet LibreOffice immer ein "defektes
// Dokument", bietet aber eine Reparatur an.
ob_start();
imagepng($image);
$imagestring = ob_get_clean();
$imagename = sprintf("Pictures/10000000%08X%08XDEADBEEF%08X.png",
imagesx($image), imagesy($image), $count);
$zipfile->addFromString($imagename, $imagestring);
$h = imagesy($image) / $px_per_cm;
$w = imagesx($image) / $px_per_cm;
$xml .= <<<EOF
<text:p text:style-name="P1">
<draw:frame draw:style-name="fr1" draw:name="Image$count" text:anchor-type="as-char" svg:width="${w}cm" svg:height="${h}cm" draw:z-index="0">
<draw:image xlink:href="$imagename" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad" loext:mime-type="image/png"/>
</draw:frame>
</text:p>
EOF;
imagedestroy($image);
}
} elseif ($o['mode'] == 'einzel' || ($o['mode'] == 'gesamt' && $o['dungeons'])) {
// Bei Einzelbildausgabe einfach PNG schreiben
imagepng($mapimage, $o['output']."/".$gebiet.".png");
imagedestroy($mapimage);
} else {
// Bei Gesamtbild traditionell JPG
// TODO was wenn ein .png als Ausgabename gewählt wurde?
imagejpeg($mapimage, $o['output']);
imagedestroy($mapimage);
}
}
if ($o["mode"] == 'atlas')
{
$old_contents = $zipfile->getFromName('content.xml');
if (!$old_contents) {
echo ATLAS_TEMPLATE." enthält keine Datei content.xml - kein .odt-Dokument?\n";
}
if (!preg_match('/(.*)<text:p[^<]*<text:span[^<]*ADD_CONTENT_HERE[^<]*<\/text:span>[^<]*<\/text:p>(.*)/', $old_contents, $matches)) {
if (!preg_match('/(.*)<text:p[^<]*ADD CONTENT HERE[^<]*<\/text:p>(.*)/', $old_contents, $matches)) {
echo "Die contents.xml im Atlas-Template entspricht nicht der erwarteten Form.\n";
echo $old_contents;
exit;
}
}
$contents = $matches[1] . $oberflaeche . $dungeons . $matches[2];
$zipfile->addFromString('content.xml', $contents);
$zipfile->close();
echo "Atlas erstellt. Die fertige Datei muss nun im OpenOffice/LibreOffice\n";
echo "geöffnet und \"repariert\" werden.\n";
}