mirror of
https://github.com/Sarjuuk/aowow.git
synced 2025-11-29 15:58:16 +08:00
Setup/img-maps
* script cleanup * fixed subzone generation and made color less garish * fixed alphamap generation and alphamapcheck not pointing to the same path * fixed padding UtilityScript args with unexpected var types
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
# cache
|
# cache
|
||||||
/cache/template/*
|
/cache/template/*
|
||||||
/setup/generated/alphaMaps/*.png
|
/cache/alphaMaps/*
|
||||||
/cache/firstrun
|
/cache/setup/*
|
||||||
|
|
||||||
# extract from MPQ
|
# extract from MPQ
|
||||||
/setup/mpqdata/*
|
/setup/mpqdata/*
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ class Game
|
|||||||
|
|
||||||
private static function alphaMapCheck(int $areaId, array &$set) : bool
|
private static function alphaMapCheck(int $areaId, array &$set) : bool
|
||||||
{
|
{
|
||||||
$file = 'setup/generated/alphaMaps/'.$areaId.'.png';
|
$file = 'cache/alphaMaps/'.$areaId.'.png';
|
||||||
if (!file_exists($file)) // file does not exist (probably instanced area)
|
if (!file_exists($file)) // file does not exist (probably instanced area)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|||||||
@@ -1151,6 +1151,7 @@ $lang = array(
|
|||||||
'Miscellaneous' => "Diverse",
|
'Miscellaneous' => "Diverse",
|
||||||
'Azeroth' => "Azeroth",
|
'Azeroth' => "Azeroth",
|
||||||
'CosmicMap' => "Kosmische Karte",
|
'CosmicMap' => "Kosmische Karte",
|
||||||
|
'floorN' => "%d. Stockwerk"
|
||||||
),
|
),
|
||||||
'privileges' => array(
|
'privileges' => array(
|
||||||
'main' => "Auf unserer Seite könnt Ihr <a href=\"?reputation\">Ruf</a> erringen. Hauptsächlich erringt man Ruf dadurch, dass Eure Kommentare positiv bewertet werden.<br><br>Das heißt, Euer Ruf hängt in gewissem Maße davon ab, wie sehr Ihr der Community beiträgt.<br><br>Mit dem Sammeln von Ruf verdient Ihr Euch auch das Vertrauen der Gemeinschaft ein, und Ihr erhält Privilegien. Unten könnt Ihr eine vollständige Liste einsehen.",
|
'main' => "Auf unserer Seite könnt Ihr <a href=\"?reputation\">Ruf</a> erringen. Hauptsächlich erringt man Ruf dadurch, dass Eure Kommentare positiv bewertet werden.<br><br>Das heißt, Euer Ruf hängt in gewissem Maße davon ab, wie sehr Ihr der Community beiträgt.<br><br>Mit dem Sammeln von Ruf verdient Ihr Euch auch das Vertrauen der Gemeinschaft ein, und Ihr erhält Privilegien. Unten könnt Ihr eine vollständige Liste einsehen.",
|
||||||
|
|||||||
@@ -1152,6 +1152,7 @@ $lang = array(
|
|||||||
'Miscellaneous' => "Miscellaneous",
|
'Miscellaneous' => "Miscellaneous",
|
||||||
'Azeroth' => "Azeroth",
|
'Azeroth' => "Azeroth",
|
||||||
'CosmicMap' => "Cosmic Map",
|
'CosmicMap' => "Cosmic Map",
|
||||||
|
'floorN' => "Level %d"
|
||||||
),
|
),
|
||||||
'privileges' => array(
|
'privileges' => array(
|
||||||
'main' => "Here on our Site you can generate <a href=\"?reputation\">reputation</a>. The main way to generate it is to get your comments upvotes.<br><br>So, reputation is a rough measure of how much you contributed to the community.<br><br>As you amass reputation you earn the community's trust and you will be granted with additional privileges. You can find a full list below.",
|
'main' => "Here on our Site you can generate <a href=\"?reputation\">reputation</a>. The main way to generate it is to get your comments upvotes.<br><br>So, reputation is a rough measure of how much you contributed to the community.<br><br>As you amass reputation you earn the community's trust and you will be granted with additional privileges. You can find a full list below.",
|
||||||
|
|||||||
@@ -1151,6 +1151,7 @@ $lang = array(
|
|||||||
'Miscellaneous' => "Miscelánea",
|
'Miscellaneous' => "Miscelánea",
|
||||||
'Azeroth' => "Azeroth",
|
'Azeroth' => "Azeroth",
|
||||||
'CosmicMap' => "Mapa cósmico",
|
'CosmicMap' => "Mapa cósmico",
|
||||||
|
'floorN' => "Nivel %d"
|
||||||
),
|
),
|
||||||
'privileges' => array(
|
'privileges' => array(
|
||||||
'main' => "Aquí, en AoWoW, puedes conseguir <a href=\"?reputation\">reputación</a>. La forma principal de conseguirla es conseguir que tus comentarios sean votados de forma positiva.<br /><br />Así pues, la reputación es algo que mide, más o menos, cúanto has contribuido a la comunidad.<br /><br />Conforme consigues reputación, te ganas la confianza de la comunidad y tendrás privilegios adicionales. Puedes encontrar una lista completa debajo.",
|
'main' => "Aquí, en AoWoW, puedes conseguir <a href=\"?reputation\">reputación</a>. La forma principal de conseguirla es conseguir que tus comentarios sean votados de forma positiva.<br /><br />Así pues, la reputación es algo que mide, más o menos, cúanto has contribuido a la comunidad.<br /><br />Conforme consigues reputación, te ganas la confianza de la comunidad y tendrás privilegios adicionales. Puedes encontrar una lista completa debajo.",
|
||||||
|
|||||||
@@ -1151,6 +1151,7 @@ $lang = array(
|
|||||||
'Miscellaneous' => "Divers",
|
'Miscellaneous' => "Divers",
|
||||||
'Azeroth' => "Azeroth",
|
'Azeroth' => "Azeroth",
|
||||||
'CosmicMap' => "Carte cosmique",
|
'CosmicMap' => "Carte cosmique",
|
||||||
|
'floorN' => "Plancher %d"
|
||||||
),
|
),
|
||||||
'privileges' => array(
|
'privileges' => array(
|
||||||
'main' => "Sur AoWoW, vous pouvez accumuler de la <a href=\"?reputation\">réputation</a>. Le principal moyen d'en accumuler est d'avoir un score élevé pour vos commentaires.<br><br>Ainsi, la réputation est une vision sommaire de vos contributions à la communauté.<br><br>En amassant de la réputation, vous gagnez le respect de la communauté et vous obtiendrez certains privilèges. Vous pouvez en trouver la liste complète ci-dessous.",
|
'main' => "Sur AoWoW, vous pouvez accumuler de la <a href=\"?reputation\">réputation</a>. Le principal moyen d'en accumuler est d'avoir un score élevé pour vos commentaires.<br><br>Ainsi, la réputation est une vision sommaire de vos contributions à la communauté.<br><br>En amassant de la réputation, vous gagnez le respect de la communauté et vous obtiendrez certains privilèges. Vous pouvez en trouver la liste complète ci-dessous.",
|
||||||
|
|||||||
@@ -1151,6 +1151,7 @@ $lang = array(
|
|||||||
'Miscellaneous' => "Разное",
|
'Miscellaneous' => "Разное",
|
||||||
'Azeroth' => "Азерот",
|
'Azeroth' => "Азерот",
|
||||||
'CosmicMap' => "Звёздная карта",
|
'CosmicMap' => "Звёздная карта",
|
||||||
|
'floorN' => "Уровень %d"
|
||||||
),
|
),
|
||||||
'privileges' => array(
|
'privileges' => array(
|
||||||
'main' => "Здесь на AoWoW вы можете зарабатывать <a href=\"?reputation\">репутацию</a>. Основной источник получения репутации — увеличение рейтинга ваших комментариев другими пользователями.<br><br>Репутация примерно измеряет количество вашего вклада в сообщество.<br><br>По мере того, как вы зарабатываете репутацию, вы получаете доверие сообщества и особые привилегии. Полный список привилегий расположен ниже.",
|
'main' => "Здесь на AoWoW вы можете зарабатывать <a href=\"?reputation\">репутацию</a>. Основной источник получения репутации — увеличение рейтинга ваших комментариев другими пользователями.<br><br>Репутация примерно измеряет количество вашего вклада в сообщество.<br><br>По мере того, как вы зарабатываете репутацию, вы получаете доверие сообщества и особые привилегии. Полный список привилегий расположен ниже.",
|
||||||
|
|||||||
@@ -1150,7 +1150,8 @@ $lang = array(
|
|||||||
'Battlegrounds' => "战场",
|
'Battlegrounds' => "战场",
|
||||||
'Miscellaneous' => "其他",
|
'Miscellaneous' => "其他",
|
||||||
'Azeroth' => "艾泽拉斯",
|
'Azeroth' => "艾泽拉斯",
|
||||||
'CosmicMap' => "宇宙地图"
|
'CosmicMap' => "宇宙地图",
|
||||||
|
'floorN' => "[Level %d]"
|
||||||
),
|
),
|
||||||
'privileges' => array(
|
'privileges' => array(
|
||||||
'main' => "在我们的网站上,你可以通过 <a href=\"?reputation\">声望</a>. 来获取特权。获取声望的主要途径是获得评论的赞同。<br><br>因此,声望是衡量你对社区的贡献程度的一个大致指标。<br><br>随着声望的积累,你将获得社区的信任,并被赋予额外的特权。以下是完整的特权列表。",
|
'main' => "在我们的网站上,你可以通过 <a href=\"?reputation\">声望</a>. 来获取特权。获取声望的主要途径是获得评论的赞同。<br><br>因此,声望是衡量你对社区的贡献程度的一个大致指标。<br><br>随着声望的积累,你将获得社区的信任,并被赋予额外的特权。以下是完整的特权列表。",
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ class CLISetup
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$args = array_pad($args, 4, []);
|
$args = array_pad($args, 4, null);
|
||||||
|
|
||||||
$success = $us->run($args);
|
$success = $us->run($args);
|
||||||
|
|
||||||
|
|||||||
@@ -483,7 +483,7 @@ class DBC
|
|||||||
|
|
||||||
$this->writeToDB();
|
$this->writeToDB();
|
||||||
|
|
||||||
$this->endCLean();
|
$this->endClean();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
private const A_THRESHOLD = 95; // alpha threshold to define subZones: set it too low and you have unspawnable areas inside a zone; set it too high and the border regions overlap
|
private const A_THRESHOLD = 95; // alpha threshold to define subZones: set it too low and you have unspawnable areas inside a zone; set it too high and the border regions overlap
|
||||||
private const COLOR_WHITE = [255, 255, 255]; // rgb
|
private const COLOR_WHITE = [255, 255, 255]; // rgb
|
||||||
private const COLOR_BLACK = [ 0, 0, 0]; // rgb
|
private const COLOR_BLACK = [ 0, 0, 0]; // rgb
|
||||||
private const COLOR_SUBZONE = [255, 64, 192, 64]; // rgba
|
private const COLOR_SUBZONE = [ 0, 230, 255, 74]; // rgba - note: rgb is 0-255, a is 0-127
|
||||||
|
|
||||||
private const AREA_FLAG_DEFAULT_FLOOR_TERRAIN = 0x004; // Default Dungeon Floor is Terrain
|
private const AREA_FLAG_DEFAULT_FLOOR_TERRAIN = 0x004; // Default Dungeon Floor is Terrain
|
||||||
private const AREA_FLAG_NO_DEFAULT_FLOOR = 0x100; // Don't use Default Dungeon Floor (typically 1)
|
private const AREA_FLAG_NO_DEFAULT_FLOOR = 0x100; // Don't use Default Dungeon Floor (typically 1)
|
||||||
@@ -54,22 +54,13 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
[9, 10, 11, 12]
|
[9, 10, 11, 12]
|
||||||
);
|
);
|
||||||
|
|
||||||
private const LEVEL_N = array( // todo: move this hackfix to locales?
|
|
||||||
LOCALE_EN => 'Level %d',
|
|
||||||
LOCALE_FR => 'Plancher %d',
|
|
||||||
LOCALE_DE => '%d. Stockwerk',
|
|
||||||
LOCALE_CN => '[Level %d]',
|
|
||||||
LOCALE_ES => 'Nivel %d',
|
|
||||||
LOCALE_RU => 'Уровень %d'
|
|
||||||
);
|
|
||||||
|
|
||||||
private const MAP_FILE_PATTERN = '/((\w{4})\/interface\/worldmap(?:\/microdungeon\/([^\/]+))?\/([^\/]+)\/)(\4)(?:(\d{1,2})_)?(\d{1,2})\.(?:blp|png)/i';
|
private const MAP_FILE_PATTERN = '/((\w{4})\/interface\/worldmap(?:\/microdungeon\/([^\/]+))?\/([^\/]+)\/)(\4)(?:(\d{1,2})_)?(\d{1,2})\.(?:blp|png)/i';
|
||||||
|
|
||||||
// src, resourcePath, localized, [tileOrder], [[dest, destW, destH]]
|
// src, resourcePath, localized, [tileOrder], [[dest, destW, destH]]
|
||||||
private $genSteps = array(
|
private $genSteps = array(
|
||||||
self::M_MAPS => ['WorldMap/', null, true, self::TILEORDER, self::DEST_DIRS ],
|
self::M_MAPS => ['WorldMap/', null, true, self::TILEORDER, self::DEST_DIRS ],
|
||||||
self::M_SPAWNS => ['WorldMap/', null, true, self::TILEORDER, [['cache/setup/alphaMaps/', 0, 0]]],
|
self::M_SPAWNS => ['WorldMap/', null, true, self::TILEORDER, [['cache/alphaMaps/', 0, 0]]],
|
||||||
self::M_SUBZONES => ['WorldMap/', null, true, self::TILEORDER, self::DEST_DIRS ]
|
self::M_SUBZONES => ['WorldMap/', null, true, self::TILEORDER, self::DEST_DIRS ]
|
||||||
);
|
);
|
||||||
|
|
||||||
private $progress = 0;
|
private $progress = 0;
|
||||||
@@ -114,8 +105,8 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
$mask |= self::M_MAPS;
|
$mask |= self::M_MAPS;
|
||||||
|
|
||||||
// unless manually prompted drop spawnmap generation if 90% of spawns have core generated area info
|
// unless manually prompted drop spawnmap generation if 90% of spawns have core generated area info
|
||||||
$npcPct = DB::World()->selectCell('SELECT SUM(IF(zoneId > 0, 1, 0)) / COUNT(*) FROM creature') ?? 0;
|
$npcPct = DB::World()->selectCell('SELECT SUM(IF(`zoneId` > 0, 1, 0)) / COUNT(*) FROM creature') ?? 0;
|
||||||
$goPct = DB::World()->selectCell('SELECT SUM(IF(zoneId > 0, 1, 0)) / COUNT(*) FROM gameobject') ?? 0;
|
$goPct = DB::World()->selectCell('SELECT SUM(IF(`zoneId` > 0, 1, 0)) / COUNT(*) FROM gameobject') ?? 0;
|
||||||
|
|
||||||
if (!($mask & self::M_SPAWNS) && $npcPct > 0.9 && $goPct > 0.9)
|
if (!($mask & self::M_SPAWNS) && $npcPct > 0.9 && $goPct > 0.9)
|
||||||
$this->modeMask &= ~self::M_SPAWNS;
|
$this->modeMask &= ~self::M_SPAWNS;
|
||||||
@@ -132,7 +123,7 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
|
|
||||||
if (!$this->checkSourceDirs())
|
if (!$this->checkSourceDirs())
|
||||||
{
|
{
|
||||||
CLI::write('one or more source directories are missing:', CLI::LOG_ERROR);
|
CLI::write('[img-maps] One or more source directories are missing.', CLI::LOG_ERROR);
|
||||||
$this->success = false;
|
$this->success = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -190,15 +181,15 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
{
|
{
|
||||||
ksort($floorData);
|
ksort($floorData);
|
||||||
|
|
||||||
$overlay = null;
|
$resOverlay = null;
|
||||||
if (!$isMultilevel)
|
if (!$isMultilevel)
|
||||||
$overlay = $this->generateOverlay($wmaId, $name, $basePath);
|
$resOverlay = $this->generateOverlay($wmaId, $name, $basePath);
|
||||||
|
|
||||||
// create spawn-maps if wanted
|
// create spawn-maps if wanted
|
||||||
if ($overlay && $this->modeMask & self::M_SPAWNS)
|
if ($resOverlay && $this->modeMask & self::M_SPAWNS)
|
||||||
{
|
{
|
||||||
$outFile = $this->genSteps[self::M_SPAWNS][self::$GEN_IDX_DEST_INFO][0][0] . $zoneId . '.png';
|
$outFile = $this->genSteps[self::M_SPAWNS][self::$GEN_IDX_DEST_INFO][0][0] . $zoneId . '.png';
|
||||||
if (!$this->generateSpawnMap($overlay, $outFile))
|
if (!$this->buildSpawnMap($resOverlay, $outFile))
|
||||||
$this->success = false;
|
$this->success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,84 +284,16 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$overlay = null;
|
$resOverlay = null;
|
||||||
|
|
||||||
// zone has overlays (is in open world; is not multilevel)
|
// zone has overlays (is in open world; is not multilevel)
|
||||||
if (isset($this->wmOverlays[$wmaId]))
|
if (isset($this->wmOverlays[$wmaId]))
|
||||||
{
|
{
|
||||||
$overlay = $this->createAlphaImage(self::MAP_W, self::MAP_H);
|
$resOverlay = $this->generateOverlay($wmaId, $srcPath);
|
||||||
|
|
||||||
foreach ($this->wmOverlays[$wmaId] as &$row)
|
|
||||||
{
|
|
||||||
$i = 1;
|
|
||||||
$y = 0;
|
|
||||||
while ($y < $row['h'])
|
|
||||||
{
|
|
||||||
$x = 0;
|
|
||||||
while ($x < $row['w'])
|
|
||||||
{
|
|
||||||
$img = $this->loadImageFile($srcPath . '/' . $row['textureString'] . $i);
|
|
||||||
if (!$img)
|
|
||||||
{
|
|
||||||
CLI::write(' - complexImg: tile '.$srcPath.'/'.$row['textureString'].$i.'.blp missing.', CLI::LOG_ERROR);
|
|
||||||
break 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
imagecopy($overlay, $img, $row['x'] + $x, $row['y'] + $y, 0, 0, imagesx($img), imagesy($img));
|
|
||||||
|
|
||||||
// prepare subzone image
|
|
||||||
if ($this->modeMask & self::M_SUBZONES)
|
|
||||||
{
|
|
||||||
if (!isset($row['maskimage']))
|
|
||||||
{
|
|
||||||
$row['maskimage'] = $this->createAlphaImage($row['w'], $row['h']);
|
|
||||||
$row['maskcolor'] = imagecolorallocatealpha($row['maskimage'], ...self::COLOR_SUBZONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
for ($my = 0; $my < imagesy($img); $my++)
|
|
||||||
for ($mx = 0; $mx < imagesx($img); $mx++)
|
|
||||||
if ((imagecolorat($img, $mx, $my) >> 24) < self::A_THRESHOLD)
|
|
||||||
imagesetpixel($row['maskimage'], $x + $mx, $y + $my, $row['maskcolor']);
|
|
||||||
}
|
|
||||||
|
|
||||||
imagedestroy($img);
|
|
||||||
|
|
||||||
$x += 256;
|
|
||||||
$i++;
|
|
||||||
}
|
|
||||||
$y += 256;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// create spawn-maps if wanted
|
// create spawn-maps if wanted
|
||||||
if ($this->modeMask & self::M_SPAWNS)
|
if ($this->modeMask & self::M_SPAWNS)
|
||||||
{
|
$this->buildSpawnMap($resOverlay, $zoneId);
|
||||||
$outFile = $this->genSteps[self::M_SPAWNS][self::$GEN_IDX_DEST_INFO][0][0] . $zoneId . '.png';
|
|
||||||
|
|
||||||
if (CLISetup::getOpt('force') || !file_exists($outFile))
|
|
||||||
{
|
|
||||||
$tmp = imagecreate(self::SPAWNMAP_WH, self::SPAWNMAP_WH);
|
|
||||||
$cbg = imagecolorallocate($tmp, ...self::COLOR_WHITE);
|
|
||||||
$cfg = imagecolorallocate($tmp, ...self::COLOR_BLACK);
|
|
||||||
|
|
||||||
for ($y = 0; $y < self::SPAWNMAP_WH; $y++)
|
|
||||||
{
|
|
||||||
for ($x = 0; $x < self::SPAWNMAP_WH; $x++)
|
|
||||||
{
|
|
||||||
$a = imagecolorat($overlay, ($x * self::MAP_W) / self::SPAWNMAP_WH, ($y * self::MAP_H) / self::SPAWNMAP_WH) >> 24;
|
|
||||||
imagesetpixel($tmp, $x, $y, $a < self::A_THRESHOLD ? $cfg : $cbg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
imagecolordeallocate($tmp, $cbg);
|
|
||||||
imagecolordeallocate($tmp, $cfg);
|
|
||||||
|
|
||||||
if (!$this->writeImageFile($tmp, $outFile, self::SPAWNMAP_WH, self::SPAWNMAP_WH))
|
|
||||||
$this->success = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
CLI::write($this->status.' - file '.$outFile.' was already processed', CLI::LOG_BLANK, true, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!($this->modeMask & self::M_MAPS))
|
if (!($this->modeMask & self::M_MAPS))
|
||||||
@@ -385,7 +308,7 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
if ($zoneId == 4494)
|
if ($zoneId == 4494)
|
||||||
$floors[] = 2;
|
$floors[] = 2;
|
||||||
|
|
||||||
$map = null;
|
$resMap = null;
|
||||||
foreach ($floors as $floorIdx)
|
foreach ($floors as $floorIdx)
|
||||||
{
|
{
|
||||||
ini_set('max_execution_time', $this->maxExecTime);
|
ini_set('max_execution_time', $this->maxExecTime);
|
||||||
@@ -430,18 +353,18 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
if ($doSkip == 0xF)
|
if ($doSkip == 0xF)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
$map = $this->assembleImage($file, self::TILEORDER, self::MAP_W, self::MAP_H);
|
$resMap = $this->assembleImage($file, self::TILEORDER, self::MAP_W, self::MAP_H);
|
||||||
if (!$map)
|
if (!$resMap)
|
||||||
{
|
{
|
||||||
CLI::write(' - could not create image resource for zone '.$zoneId.($nFloors ? ' floor '.$floorIdx : ''), CLI::LOG_ERROR);
|
CLI::write(' - could not create image resource for zone '.$zoneId.($nFloors ? ' floor '.$floorIdx : ''), CLI::LOG_ERROR);
|
||||||
$this->success = false;
|
$this->success = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($overlay && !$floorIdx)
|
if ($resOverlay && !$floorIdx)
|
||||||
{
|
{
|
||||||
imagecopymerge($map, $overlay, 0, 0, 0, 0, imagesx($overlay), imagesy($overlay), 100);
|
imagecopymerge($resMap, $resOverlay, 0, 0, 0, 0, imagesx($resOverlay), imagesy($resOverlay), 100);
|
||||||
imagedestroy($overlay);
|
imagedestroy($resOverlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create map
|
// create map
|
||||||
@@ -452,52 +375,18 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
if ($doSkip & (1 << $sizeIdx))
|
if ($doSkip & (1 << $sizeIdx))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!$this->writeImageFile($map, $outFile[$sizeIdx], $width ?: self::MAP_W, $height ?: self::MAP_H))
|
if (!$this->writeImageFile($resMap, $outFile[$sizeIdx], $width ?: self::MAP_W, $height ?: self::MAP_H))
|
||||||
$this->success = false;
|
$this->success = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// also create subzone-maps
|
// also create subzone-maps
|
||||||
if ($map && isset($this->wmOverlays[$wmaId]) && $this->modeMask & self::M_SUBZONES)
|
if ($resMap && isset($this->wmOverlays[$wmaId]) && $this->modeMask & self::M_SUBZONES)
|
||||||
{
|
$this->buildSubZones($resMap, $wmaId, $l);
|
||||||
foreach ($this->wmOverlays[$wmaId] as &$row)
|
|
||||||
{
|
|
||||||
$doSkip = 0x0;
|
|
||||||
$outFile = [];
|
|
||||||
|
|
||||||
foreach (self::DEST_DIRS as $sizeIdx => [$path, , ])
|
if ($resMap)
|
||||||
{
|
imagedestroy($resMap);
|
||||||
$outFile[$sizeIdx] = sprintf($path, strtolower(Util::$localeStrings[$l]).'/') . $row['areaTableId'].'.jpg';
|
|
||||||
if (!CLISetup::getOpt('force') && file_exists($outFile[$sizeIdx]))
|
|
||||||
{
|
|
||||||
CLI::write($this->status.' - file '.$outFile[$sizeIdx].' was already processed', CLI::LOG_BLANK, true, true);
|
|
||||||
$doSkip |= (1 << $sizeIdx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($doSkip == 0xF)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$subZone = imagecreatetruecolor(self::MAP_W, self::MAP_H);
|
|
||||||
imagecopy($subZone, $map, 0, 0, 0, 0, imagesx($map), imagesy($map));
|
|
||||||
imagecopy($subZone, $row['maskimage'], $row['x'], $row['y'], 0, 0, imagesx($row['maskimage']), imagesy($row['maskimage']));
|
|
||||||
|
|
||||||
foreach (self::DEST_DIRS as $sizeIdx => [, $width, $height])
|
|
||||||
{
|
|
||||||
if ($doSkip & (1 << $sizeIdx))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!$this->writeImageFile($subZone, $outFile[$sizeIdx], $width ?: self::MAP_W, $height ?: self::MAP_H))
|
|
||||||
$this->success = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
imagedestroy($subZone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($map)
|
|
||||||
imagedestroy($map);
|
|
||||||
|
|
||||||
// this takes a while; ping mysql just in case
|
// this takes a while; ping mysql just in case
|
||||||
DB::Aowow()->selectCell('SELECT 1');
|
DB::Aowow()->selectCell('SELECT 1');
|
||||||
@@ -512,7 +401,7 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
$this->dmFloorData = DB::Aowow()->select('SELECT IF(`mapId` IN (?a), -`worldMapAreaId`, `mapId`) AS ARRAY_KEY, GROUP_CONCAT(DISTINCT `floor` SEPARATOR " ") AS "0", COUNT(DISTINCT `floor`) AS "1" FROM dbc_dungeonmap WHERE `worldMapAreaId` <> 0 GROUP BY ARRAY_KEY', self::CONTINENTS);
|
$this->dmFloorData = DB::Aowow()->select('SELECT IF(`mapId` IN (?a), -`worldMapAreaId`, `mapId`) AS ARRAY_KEY, GROUP_CONCAT(DISTINCT `floor` SEPARATOR " ") AS "0", COUNT(DISTINCT `floor`) AS "1" FROM dbc_dungeonmap WHERE `worldMapAreaId` <> 0 GROUP BY ARRAY_KEY', self::CONTINENTS);
|
||||||
if (!$this->wmOverlays || !$this->wmAreas || !$this->dmFloorData)
|
if (!$this->wmOverlays || !$this->wmAreas || !$this->dmFloorData)
|
||||||
{
|
{
|
||||||
CLI::write(' - could not read required dbc files: WorldMapArea.dbc ['.count($this->wmAreas ?: []).' entries]; WorldMapOverlay.dbc ['.count($this->wmOverlays ?: []).'] entries; DungeonMap.dbc ['.count($this->dmFloorData ?: []).' entries]', CLI::LOG_ERROR);
|
CLI::write('[img-maps] - could not read required dbc files: WorldMapArea.dbc ['.count($this->wmAreas ?: []).' entries]; WorldMapOverlay.dbc ['.count($this->wmOverlays ?: []).'] entries; DungeonMap.dbc ['.count($this->dmFloorData ?: []).' entries]', CLI::LOG_ERROR);
|
||||||
$this->success = false;
|
$this->success = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -616,7 +505,7 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
$sumAreas = count($this->wmAreas);
|
$sumAreas = count($this->wmAreas);
|
||||||
$sumMaps = count(CLISetup::$localeIds) * ($sumAreas + $sumFloors);
|
$sumMaps = count(CLISetup::$localeIds) * ($sumAreas + $sumFloors);
|
||||||
|
|
||||||
CLI::write('Processing '.$sumAreas.' zone maps and '.$sumFloors.' dungeon maps from Interface/WorldMap/ for locale: '.Lang::concat(array_intersect_key(Util::$localeStrings, array_flip(CLISetup::$localeIds))));
|
CLI::write('[img-maps] Processing '.$sumAreas.' zone maps and '.$sumFloors.' dungeon maps from Interface/WorldMap/ for locale: '.Lang::concat(array_intersect_key(Util::$localeStrings, array_flip(CLISetup::$localeIds))));
|
||||||
|
|
||||||
foreach (CLISetup::$localeIds as $l)
|
foreach (CLISetup::$localeIds as $l)
|
||||||
{
|
{
|
||||||
@@ -630,13 +519,16 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
$mapSrcDir = $this->genSteps[self::M_MAPS][1][$l] ?? '';
|
$mapSrcDir = $this->genSteps[self::M_MAPS][1][$l] ?? '';
|
||||||
if (!$mapSrcDir)
|
if (!$mapSrcDir)
|
||||||
{
|
{
|
||||||
|
CLI::write('[img-maps] - No suitable localized map files found for locale ['.$l.': '.Util::$localeStrings[$l].'].', CLI::LOG_ERROR);
|
||||||
$this->success = false;
|
$this->success = false;
|
||||||
CLI::write(' - no suitable localized map files found for locale '.$l, CLI::LOG_ERROR);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->wmAreas as $areaEntry)
|
foreach ($this->wmAreas as $areaEntry)
|
||||||
{
|
{
|
||||||
|
$resOverlay = null;
|
||||||
|
$resMap = null;
|
||||||
|
|
||||||
$wmaId = $areaEntry['id'];
|
$wmaId = $areaEntry['id'];
|
||||||
$zoneId = $areaEntry['areaId'];
|
$zoneId = $areaEntry['areaId'];
|
||||||
$mapId = $areaEntry['mapId'];
|
$mapId = $areaEntry['mapId'];
|
||||||
@@ -672,109 +564,40 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
$srcPath = $mapSrcDir.'/'.$textureStr;
|
$srcPath = $mapSrcDir.'/'.$textureStr;
|
||||||
if (!CLISetup::fileExists($srcPath))
|
if (!CLISetup::fileExists($srcPath))
|
||||||
{
|
{
|
||||||
|
CLI::write('[img-maps] - WorldMap file path '.$srcPath.' missing for selected locale '.Util::$localeStrings[$l], CLI::LOG_ERROR);
|
||||||
$this->success = false;
|
$this->success = false;
|
||||||
CLI::write('worldmap file path '.$srcPath.' missing for selected locale '.Util::$localeStrings[$l], CLI::LOG_ERROR);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$overlay = null;
|
$srcPath .= '/';
|
||||||
|
|
||||||
// zone has overlays (is in open world; is not multilevel)
|
// zone has overlays (is in open world; is not multilevel)
|
||||||
if (isset($this->wmOverlays[$wmaId]) && ($this->modeMask & (self::M_MAPS | self::M_SPAWNS | self::M_SUBZONES)))
|
if (isset($this->wmOverlays[$wmaId]) && ($this->modeMask & (self::M_MAPS | self::M_SPAWNS | self::M_SUBZONES)))
|
||||||
{
|
{
|
||||||
$overlay = $this->createAlphaImage(self::MAP_W, self::MAP_H);
|
$resOverlay = $this->generateOverlay($wmaId, $srcPath);
|
||||||
|
|
||||||
foreach ($this->wmOverlays[$wmaId] as &$row)
|
|
||||||
{
|
|
||||||
$i = 1;
|
|
||||||
$y = 0;
|
|
||||||
while ($y < $row['h'])
|
|
||||||
{
|
|
||||||
$x = 0;
|
|
||||||
while ($x < $row['w'])
|
|
||||||
{
|
|
||||||
$img = $this->loadImageFile($srcPath . '/' . $row['textureString'] . $i);
|
|
||||||
if (!$img)
|
|
||||||
{
|
|
||||||
CLI::write(' - complexImg: tile '.$srcPath.'/'.$row['textureString'].$i.'.blp missing.', CLI::LOG_ERROR);
|
|
||||||
break 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
imagecopy($overlay, $img, $row['x'] + $x, $row['y'] + $y, 0, 0, imagesx($img), imagesy($img));
|
|
||||||
|
|
||||||
// prepare subzone image
|
|
||||||
if ($this->modeMask & self::M_SUBZONES)
|
|
||||||
{
|
|
||||||
if (!isset($row['maskimage']))
|
|
||||||
{
|
|
||||||
$row['maskimage'] = $this->createAlphaImage($row['w'], $row['h']);
|
|
||||||
$row['maskcolor'] = imagecolorallocatealpha($row['maskimage'], ...self::COLOR_SUBZONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
for ($my = 0; $my < imagesy($img); $my++)
|
|
||||||
for ($mx = 0; $mx < imagesx($img); $mx++)
|
|
||||||
if ((imagecolorat($img, $mx, $my) >> 24) < self::A_THRESHOLD)
|
|
||||||
imagesetpixel($row['maskimage'], $x + $mx, $y + $my, $row['maskcolor']);
|
|
||||||
}
|
|
||||||
|
|
||||||
imagedestroy($img);
|
|
||||||
|
|
||||||
$x += 256;
|
|
||||||
$i++;
|
|
||||||
}
|
|
||||||
$y += 256;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// create spawn-maps if wanted
|
// create spawn-maps if wanted
|
||||||
if ($this->modeMask & self::M_SPAWNS)
|
if ($resOverlay && ($this->modeMask & self::M_SPAWNS))
|
||||||
{
|
$this->buildSpawnMap($resOverlay, $zoneId);
|
||||||
$outFile = $this->genSteps[self::M_SPAWNS][self::$GEN_IDX_DEST_INFO][0][0] . $zoneId . '.png';
|
|
||||||
|
|
||||||
if (CLISetup::getOpt('force') || !file_exists($outFile))
|
|
||||||
{
|
|
||||||
$tmp = imagecreate(self::SPAWNMAP_WH, self::SPAWNMAP_WH);
|
|
||||||
$cbg = imagecolorallocate($tmp, ...self::COLOR_WHITE);
|
|
||||||
$cfg = imagecolorallocate($tmp, ...self::COLOR_BLACK);
|
|
||||||
|
|
||||||
for ($y = 0; $y < self::SPAWNMAP_WH; $y++)
|
|
||||||
{
|
|
||||||
for ($x = 0; $x < self::SPAWNMAP_WH; $x++)
|
|
||||||
{
|
|
||||||
$a = imagecolorat($overlay, ($x * self::MAP_W) / self::SPAWNMAP_WH, ($y * self::MAP_H) / self::SPAWNMAP_WH) >> 24;
|
|
||||||
imagesetpixel($tmp, $x, $y, $a < self::A_THRESHOLD ? $cfg : $cbg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
imagecolordeallocate($tmp, $cbg);
|
|
||||||
imagecolordeallocate($tmp, $cfg);
|
|
||||||
|
|
||||||
if (!$this->writeImageFile($tmp, $outFile, self::SPAWNMAP_WH, self::SPAWNMAP_WH))
|
|
||||||
$this->success = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
CLI::write($this->status.' - file '.$outFile.' was already processed', CLI::LOG_BLANK, true, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we can create base map anyway
|
// check if we can create base map anyway
|
||||||
$png = $srcPath.'/'.$textureStr.'1.png';
|
$png = $srcPath.$textureStr.'1.png';
|
||||||
$blp = $srcPath.'/'.$textureStr.'1.blp';
|
$blp = $srcPath.$textureStr.'1.blp';
|
||||||
$hasBaseMap = CLISetup::fileExists($blp) || CLISetup::fileExists($png);
|
$hasBaseMap = CLISetup::fileExists($blp) || CLISetup::fileExists($png);
|
||||||
|
|
||||||
$map = null;
|
|
||||||
foreach ($dmFloors as $srcFloorIdx => $outFloorIdx)
|
foreach ($dmFloors as $srcFloorIdx => $outFloorIdx)
|
||||||
{
|
{
|
||||||
ini_set('max_execution_time', $this->maxExecTime);
|
ini_set('max_execution_time', $this->maxExecTime);
|
||||||
|
|
||||||
$doSkip = 0x0;
|
$doSkip = 0x0;
|
||||||
$outPaths = [];
|
$outPaths = [];
|
||||||
$srcFile = $srcPath.'/'.$textureStr;
|
$srcFile = $srcPath.$textureStr;
|
||||||
$outFile = $zoneId;
|
$outFile = $zoneId;
|
||||||
|
|
||||||
if (!$srcFloorIdx && !$hasBaseMap)
|
if (!$srcFloorIdx && !$hasBaseMap)
|
||||||
{
|
{
|
||||||
CLI::Write('[img-maps] zone has no base floor, but it is referenced with base floor in dmFloors? Smells like an error. areaId: '.$zoneId, CLI::LOG_WARN);
|
CLI::write('[img-maps] - Zone has no base floor, but is referenced with base floor in dmFloors.', CLI::LOG_WARN);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -802,21 +625,22 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($doSkip == 0xF)
|
// can't skip map creation if we are to generate subzones later. although they may already exist and get skipped anyway *shrug*
|
||||||
|
if ($doSkip == 0xF && !($this->modeMask & self::M_SUBZONES))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
$map = $this->assembleImage($srcFile, self::TILEORDER, self::MAP_W, self::MAP_H);
|
$resMap = $this->assembleImage($srcFile, self::TILEORDER, self::MAP_W, self::MAP_H);
|
||||||
if (!$map)
|
if (!$resMap)
|
||||||
{
|
{
|
||||||
CLI::write(' - could not create image resource for zone '.$zoneId.($nFloors ? ' floor '.$srcFloorIdx : ''));
|
CLI::write('[img-maps] - Could not create image resource for '.($nFloors ? 'floor '.$srcFloorIdx : 'base level'), CLI::LOG_ERROR);
|
||||||
$this->success = false;
|
$this->success = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($overlay && !$nFloors)
|
if ($resOverlay && !$nFloors)
|
||||||
{
|
{
|
||||||
imagecopymerge($map, $overlay, 0, 0, 0, 0, imagesx($overlay), imagesy($overlay), 100);
|
imagecopymerge($resMap, $resOverlay, 0, 0, 0, 0, imagesx($resOverlay), imagesy($resOverlay), 100);
|
||||||
imagedestroy($overlay);
|
imagedestroy($resOverlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create map
|
// create map
|
||||||
@@ -827,52 +651,18 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
if ($doSkip & (1 << $sizeIdx))
|
if ($doSkip & (1 << $sizeIdx))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!$this->writeImageFile($map, $outPaths[$sizeIdx], $width ?: self::MAP_W, $height ?: self::MAP_H))
|
if (!$this->writeImageFile($resMap, $outPaths[$sizeIdx], $width ?: self::MAP_W, $height ?: self::MAP_H))
|
||||||
$this->success = false;
|
$this->success = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// also create subzone-maps
|
// also create subzone-maps
|
||||||
if ($map && isset($this->wmOverlays[$wmaId]) && $this->modeMask & self::M_SUBZONES)
|
if ($resMap && isset($this->wmOverlays[$wmaId]) && $this->modeMask & self::M_SUBZONES)
|
||||||
{
|
$this->buildSubZones($resMap, $wmaId, $l);
|
||||||
foreach ($this->wmOverlays[$wmaId] as &$row)
|
|
||||||
{
|
|
||||||
$doSkip = 0x0;
|
|
||||||
$outFiles = [];
|
|
||||||
|
|
||||||
foreach (self::DEST_DIRS as $sizeIdx => [$path, , ])
|
if ($resMap)
|
||||||
{
|
imagedestroy($resMap);
|
||||||
$outFile[$sizeIdx] = sprintf($path, strtolower(Util::$localeStrings[$l]).'/') . $row['areaTableId'].'.jpg';
|
|
||||||
if (!CLISetup::getOpt('force') && file_exists($outFiles[$sizeIdx]))
|
|
||||||
{
|
|
||||||
CLI::write($this->status.' - file '.$outFiles[$sizeIdx].' was already processed', CLI::LOG_BLANK, true, true);
|
|
||||||
$doSkip |= (1 << $sizeIdx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($doSkip == 0xF)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$subZone = imagecreatetruecolor(self::MAP_W, self::MAP_H);
|
|
||||||
imagecopy($subZone, $map, 0, 0, 0, 0, imagesx($map), imagesy($map));
|
|
||||||
imagecopy($subZone, $row['maskimage'], $row['x'], $row['y'], 0, 0, imagesx($row['maskimage']), imagesy($row['maskimage']));
|
|
||||||
|
|
||||||
foreach (self::DEST_DIRS as $sizeIdx => [, $width, $height])
|
|
||||||
{
|
|
||||||
if ($doSkip & (1 << $sizeIdx))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!$this->writeImageFile($subZone, $outFiles[$sizeIdx], $width ?: self::MAP_W, $height ?: self::MAP_H))
|
|
||||||
$this->success = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
imagedestroy($subZone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($map)
|
|
||||||
imagedestroy($map);
|
|
||||||
|
|
||||||
// this takes a while; ping mysql just in case
|
// this takes a while; ping mysql just in case
|
||||||
DB::Aowow()->selectCell('SELECT 1');
|
DB::Aowow()->selectCell('SELECT 1');
|
||||||
@@ -880,7 +670,7 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildZonesFile() : bool
|
private function buildZonesFile() : void
|
||||||
{
|
{
|
||||||
$areaNames = array_combine(
|
$areaNames = array_combine(
|
||||||
array_column($this->wmAreas, 'areaId'),
|
array_column($this->wmAreas, 'areaId'),
|
||||||
@@ -910,14 +700,16 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
$zoneAreas[$lId][$zId][$floor] = $nameLOC;
|
$zoneAreas[$lId][$zId][$floor] = $nameLOC;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
CLI::write('[img-maps] internal zone name from GlobalStrings.lua not found in WorldMapArea.dbc ['.$nameINT.']', CLI::LOG_WARN);
|
CLI::write('[img-maps] ['.$nameINT.'] from GlobalStrings.lua not found in WorldMapArea.dbc', CLI::LOG_WARN);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (CLISetup::$locales as $lId => $loc)
|
foreach (CLISetup::$locales as $lId => $loc)
|
||||||
{
|
{
|
||||||
|
Lang::load($lId);
|
||||||
|
|
||||||
// "custom" - show second level of Ahn'Kahet not shown but present in-game
|
// "custom" - show second level of Ahn'Kahet not shown but present in-game
|
||||||
if (isset($zoneAreas[$lId][4494]))
|
if (isset($zoneAreas[$lId][4494]))
|
||||||
$zoneAreas[$lId][4494][2] = sprintf(self::LEVEL_N[$lId], 2);
|
$zoneAreas[$lId][4494][2] = Lang::maps('floorN', [2]);
|
||||||
|
|
||||||
foreach ($zoneAreas[$lId] as $zoneId => $floorData)
|
foreach ($zoneAreas[$lId] as $zoneId => $floorData)
|
||||||
{
|
{
|
||||||
@@ -927,7 +719,7 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// todo: just note for now, try to compensate later?
|
// todo: just note for now, try to compensate later?
|
||||||
CLI::write('[img-maps] floor count mismatch for zone #'.$zoneId.' GlobalStrings: '.$nStrings.' image files: '.$nFloors, CLI::LOG_WARN);
|
CLI::write('[img-maps] ['.$loc.'] '.str_pad('['.$zoneId.']', 7).'floor count mismatch between GlobalStrings: '.$nStrings.' and image files: '.$nFloors, CLI::LOG_WARN);
|
||||||
}
|
}
|
||||||
|
|
||||||
ksort($zoneAreas[$lId]);
|
ksort($zoneAreas[$lId]);
|
||||||
@@ -942,75 +734,24 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
if (!CLISetup::writeFile($file, $toFile))
|
if (!CLISetup::writeFile($file, $toFile))
|
||||||
$this->success = false;
|
$this->success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function generateOverlay(int $wmaId, string $name, string $basePath) // : ?GdImage
|
private function buildSpawnMap(/*GdImage*/ $resOverlay, int $zoneId) : void
|
||||||
{
|
|
||||||
if (!isset($this->wmOverlays[$wmaId]))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$overlay = $this->createAlphaImage(self::MAP_W, self::MAP_H);
|
|
||||||
|
|
||||||
foreach ($this->wmOverlays[$wmaId] as &$this->wmOverlays)
|
|
||||||
{
|
|
||||||
$i = 1;
|
|
||||||
$y = 0;
|
|
||||||
while ($y < $this->wmOverlays['h'])
|
|
||||||
{
|
|
||||||
$x = 0;
|
|
||||||
while ($x < $this->wmOverlays['w'])
|
|
||||||
{
|
|
||||||
$img = $this->loadImageFile($basePath . $name . $i);
|
|
||||||
if (!$img)
|
|
||||||
{
|
|
||||||
CLI::write(' - complexImg: tile '.$basePath.$name.$i.'.blp missing.', CLI::LOG_ERROR);
|
|
||||||
break 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
imagecopy($overlay, $img, $this->wmOverlays['x'] + $x, $this->wmOverlays['y'] + $y, 0, 0, imagesx($img), imagesy($img));
|
|
||||||
|
|
||||||
// prepare subzone image
|
|
||||||
if ($this->modeMask & self::M_SUBZONES)
|
|
||||||
{
|
|
||||||
if (!isset($this->wmOverlays['maskimage']))
|
|
||||||
{
|
|
||||||
$this->wmOverlays['maskimage'] = $this->createAlphaImage($this->wmOverlays['w'], $this->wmOverlays['h']);
|
|
||||||
$this->wmOverlays['maskcolor'] = imagecolorallocatealpha($this->wmOverlays['maskimage'], ...self::COLOR_SUBZONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
for ($my = 0; $my < imagesy($img); $my++)
|
|
||||||
for ($mx = 0; $mx < imagesx($img); $mx++)
|
|
||||||
if ((imagecolorat($img, $mx, $my) >> 24) < self::A_THRESHOLD)
|
|
||||||
imagesetpixel($this->wmOverlays['maskimage'], $x + $mx, $y + $my, $this->wmOverlays['maskcolor']);
|
|
||||||
}
|
|
||||||
|
|
||||||
imagedestroy($img);
|
|
||||||
|
|
||||||
$x += 256;
|
|
||||||
$i++;
|
|
||||||
}
|
|
||||||
$y += 256;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $overlay;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function generateSpawnMap(/*GdImage*/ $overlay, string $outFile) : bool
|
|
||||||
{
|
{
|
||||||
// GdImage: < 8.0 resource; >= 8.0 object
|
// GdImage: < 8.0 resource; >= 8.0 object
|
||||||
if (gettype($overlay) != 'resource' && gettype($overlay) != 'object')
|
if (gettype($resOverlay) != 'resource' && gettype($resOverlay) != 'object')
|
||||||
{
|
{
|
||||||
CLI::write('[img-maps] no GdImage passed to generateSpawnMap', CLI::LOG_ERROR);
|
CLI::write('[img-maps] - no GdImage passed to buildSpawnMap', CLI::LOG_ERROR);
|
||||||
return false;
|
$this->success = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$outFile = $this->genSteps[self::M_SPAWNS][self::$GEN_IDX_DEST_INFO][0][0] . $zoneId . '.png';
|
||||||
|
|
||||||
if (!CLISetup::getOpt('force') && file_exists($outFile))
|
if (!CLISetup::getOpt('force') && file_exists($outFile))
|
||||||
{
|
{
|
||||||
CLI::write($this->status.' - file '.$outFile.' was already processed', CLI::LOG_BLANK, true, true);
|
CLI::write($this->status.' - file '.$outFile.' was already processed', CLI::LOG_BLANK, true, true);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$tmp = imagecreate(self::SPAWNMAP_WH, self::SPAWNMAP_WH);
|
$tmp = imagecreate(self::SPAWNMAP_WH, self::SPAWNMAP_WH);
|
||||||
@@ -1021,7 +762,7 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
{
|
{
|
||||||
for ($x = 0; $x < self::SPAWNMAP_WH; $x++)
|
for ($x = 0; $x < self::SPAWNMAP_WH; $x++)
|
||||||
{
|
{
|
||||||
$a = imagecolorat($overlay, ($x * self::MAP_W) / self::SPAWNMAP_WH, ($y * self::MAP_H) / self::SPAWNMAP_WH) >> 24;
|
$a = imagecolorat($resOverlay, ($x * self::MAP_W) / self::SPAWNMAP_WH, ($y * self::MAP_H) / self::SPAWNMAP_WH) >> 24;
|
||||||
imagesetpixel($tmp, $x, $y, $a < self::A_THRESHOLD ? $cfg : $cbg);
|
imagesetpixel($tmp, $x, $y, $a < self::A_THRESHOLD ? $cfg : $cbg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1029,16 +770,18 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
imagecolordeallocate($tmp, $cbg);
|
imagecolordeallocate($tmp, $cbg);
|
||||||
imagecolordeallocate($tmp, $cfg);
|
imagecolordeallocate($tmp, $cfg);
|
||||||
|
|
||||||
return $this->writeImageFile($tmp, $outFile, self::SPAWNMAP_WH, self::SPAWNMAP_WH);
|
if (!$this->writeImageFile($tmp, $outFile, self::SPAWNMAP_WH, self::SPAWNMAP_WH))
|
||||||
|
$this->success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function generateSubZones(/*GdImage*/ $map, int $wmaId, int $locId) : bool
|
private function buildSubZones(/*GdImage*/ $resMap, int $wmaId, int $locId) : void
|
||||||
{
|
{
|
||||||
// GdImage: < 8.0 resource; >= 8.0 object
|
// GdImage: < 8.0 resource; >= 8.0 object
|
||||||
if (gettype($map) != 'resource' && gettype($map) != 'object')
|
if (gettype($resMap) != 'resource' && gettype($resMap) != 'object')
|
||||||
{
|
{
|
||||||
CLI::write('[img-maps] no GdImage passed to generateSubZones', CLI::LOG_ERROR);
|
CLI::write('[img-maps] - no GdImage passed to buildSubZones()', CLI::LOG_ERROR);
|
||||||
return false;
|
$this->success = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->wmOverlays[$wmaId] as &$row)
|
foreach ($this->wmOverlays[$wmaId] as &$row)
|
||||||
@@ -1060,7 +803,7 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
$subZone = imagecreatetruecolor(self::MAP_W, self::MAP_H);
|
$subZone = imagecreatetruecolor(self::MAP_W, self::MAP_H);
|
||||||
imagecopy($subZone, $map, 0, 0, 0, 0, imagesx($map), imagesy($map));
|
imagecopy($subZone, $resMap, 0, 0, 0, 0, imagesx($resMap), imagesy($resMap));
|
||||||
imagecopy($subZone, $row['maskimage'], $row['x'], $row['y'], 0, 0, imagesx($row['maskimage']), imagesy($row['maskimage']));
|
imagecopy($subZone, $row['maskimage'], $row['x'], $row['y'], 0, 0, imagesx($row['maskimage']), imagesy($row['maskimage']));
|
||||||
|
|
||||||
foreach (self::DEST_DIRS as $sizeIdx => [, $width, $height])
|
foreach (self::DEST_DIRS as $sizeIdx => [, $width, $height])
|
||||||
@@ -1074,8 +817,58 @@ CLISetup::registerSetup("build", new class extends SetupScript
|
|||||||
|
|
||||||
imagedestroy($subZone);
|
imagedestroy($subZone);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
private function generateOverlay(int $wmaId, string $basePath) // : ?GdImage
|
||||||
|
{
|
||||||
|
if (!isset($this->wmOverlays[$wmaId]))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
$resOverlay = $this->createAlphaImage(self::MAP_W, self::MAP_H);
|
||||||
|
|
||||||
|
foreach ($this->wmOverlays[$wmaId] as &$row)
|
||||||
|
{
|
||||||
|
$i = 1;
|
||||||
|
$y = 0;
|
||||||
|
while ($y < $row['h'])
|
||||||
|
{
|
||||||
|
$x = 0;
|
||||||
|
while ($x < $row['w'])
|
||||||
|
{
|
||||||
|
$img = $this->loadImageFile($basePath . $row['textureString'] . $i);
|
||||||
|
if (!$img)
|
||||||
|
{
|
||||||
|
CLI::write('[img-maps] - overlay tile ' . $basePath . $row['textureString'] . $i . '.blp missing.', CLI::LOG_ERROR);
|
||||||
|
break 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
imagecopy($resOverlay, $img, $row['x'] + $x, $row['y'] + $y, 0, 0, imagesx($img), imagesy($img));
|
||||||
|
|
||||||
|
// prepare subzone image
|
||||||
|
if ($this->modeMask & self::M_SUBZONES)
|
||||||
|
{
|
||||||
|
if (!isset($row['maskimage']))
|
||||||
|
{
|
||||||
|
$row['maskimage'] = $this->createAlphaImage($row['w'], $row['h']);
|
||||||
|
$row['maskcolor'] = imagecolorallocatealpha($row['maskimage'], ...self::COLOR_SUBZONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($my = 0; $my < imagesy($img); $my++)
|
||||||
|
for ($mx = 0; $mx < imagesx($img); $mx++)
|
||||||
|
if ((imagecolorat($img, $mx, $my) >> 24) < self::A_THRESHOLD)
|
||||||
|
imagesetpixel($row['maskimage'], $x + $mx, $y + $my, $row['maskcolor']);
|
||||||
|
}
|
||||||
|
|
||||||
|
imagedestroy($img);
|
||||||
|
|
||||||
|
$x += 256;
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
$y += 256;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $resOverlay;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user