mirror of
https://github.com/Sarjuuk/aowow.git
synced 2025-11-29 15:58:16 +08:00
Map/Spawns
* move areatrigger teleport endpoints and instance entrance points to spawns. This makes them editable like spawn points. * since instance entrances aren't shown on maps they are moved through the admin menu on the instances page. * rewrote spawns SetupScript. Individual groups can now be recalculated separately.
This commit is contained in:
@@ -383,7 +383,7 @@ class AjaxAdmin extends AjaxHandler
|
||||
$area = $this->_get['area'];
|
||||
$floor = $this->_get['floor'];
|
||||
|
||||
if (!in_array($type, [Type::NPC, Type::OBJECT, Type::SOUND, Type::AREATRIGGER]))
|
||||
if (!in_array($type, [Type::NPC, Type::OBJECT, Type::SOUND, Type::AREATRIGGER, Type::ZONE]))
|
||||
return '-3';
|
||||
|
||||
DB::Aowow()->query('REPLACE INTO ?_spawns_override VALUES (?d, ?d, ?d, ?d, ?d)', $type, $guid, $area, $floor, AOWOW_REVISION);
|
||||
|
||||
@@ -591,14 +591,16 @@ trait spawnHelper
|
||||
return;
|
||||
|
||||
if (User::isInGroup(U_GROUP_MODERATOR))
|
||||
if ($guids = array_filter(array_column($spawns, 'guid'), function ($x) { return $x > 0; }))
|
||||
if ($guids = array_column(array_filter($spawns, function ($x) { return $x['guid'] > 0 || $x['type'] != Type::NPC; }), 'guid'))
|
||||
$worldPos = Game::getWorldPosForGUID(self::$type, ...$guids);
|
||||
|
||||
foreach ($spawns as $s)
|
||||
{
|
||||
$isAccessory = $s['guid'] < 0 && $s['type'] == Type::NPC;
|
||||
|
||||
// check, if we can attach waypoints to creature
|
||||
// we will get a nice clusterfuck of dots if we do this for more GUIDs, than we have colors though
|
||||
if (count($spawns) < 6 && self::$type == Type::NPC)
|
||||
if (count($spawns) < 6 && $s['type'] == Type::NPC)
|
||||
{
|
||||
if ($wPoints = DB::Aowow()->select('SELECT * FROM ?_creature_waypoints WHERE creatureOrPath = ?d AND floor = ?d', $s['pathId'] ? -$s['pathId'] : $this->id, $s['floor']))
|
||||
{
|
||||
@@ -641,7 +643,10 @@ trait spawnHelper
|
||||
|
||||
if (User::isInGroup(U_GROUP_STAFF))
|
||||
{
|
||||
$info[0] = $s['guid'] < 0 ? 'Vehicle Accessory' : 'GUID'.Lang::main('colon').$s['guid'];
|
||||
if ($isAccessory)
|
||||
$info[0] = 'Vehicle Accessory';
|
||||
else if ($s['guid'] > 0 && ($s['type'] == Type::NPC || $s['type'] == Type::OBJECT))
|
||||
$info[0] = 'GUID'.Lang::main('colon').$s['guid'];
|
||||
|
||||
if ($s['phaseMask'] > 1 && ($s['phaseMask'] & 0xFFFF) != 0xFFFF)
|
||||
$info[2] = Lang::game('phases').Lang::main('colon').Util::asHex($s['phaseMask']);
|
||||
@@ -658,56 +663,27 @@ trait spawnHelper
|
||||
$info[4] = Lang::game('mode').Lang::main('colon').implode(', ', $_);
|
||||
}
|
||||
|
||||
if (self::$type == Type::AREATRIGGER)
|
||||
if ($s['type'] == Type::AREATRIGGER)
|
||||
{
|
||||
$o = Util::O2Deg($this->getField('orientation'));
|
||||
$info[5] = 'Orientation'.Lang::main('colon').$o[0].'° ('.$o[1].')';
|
||||
// teleporter endpoint
|
||||
if ($s['guid'] < 0)
|
||||
{
|
||||
$opts['type'] = 4;
|
||||
$info[5] = 'Teleport Destination';
|
||||
}
|
||||
else
|
||||
{
|
||||
$o = Util::O2Deg($this->getField('orientation'));
|
||||
$info[5] = 'Orientation'.Lang::main('colon').$o[0].'° ('.$o[1].')';
|
||||
}
|
||||
}
|
||||
|
||||
// guid < 0 are vehicle accessories. those are moved by moving the vehicle
|
||||
if (User::isInGroup(U_GROUP_MODERATOR) && $worldPos && $s['guid'] > 0 && isset($worldPos[$s['guid']]))
|
||||
{
|
||||
if ($points = Game::worldPosToZonePos($worldPos[$s['guid']]['mapId'], $worldPos[$s['guid']]['posX'], $worldPos[$s['guid']]['posY']))
|
||||
{
|
||||
$floors = [];
|
||||
foreach ($points as $p)
|
||||
{
|
||||
if ($p['multifloor'])
|
||||
$floors[$p['areaId']][] = $p['floor'];
|
||||
if (User::isInGroup(U_GROUP_MODERATOR) && $worldPos && !$isAccessory && isset($worldPos[$s['guid']]))
|
||||
$menu = Util::buildPosFixMenu($worldPos[$s['guid']]['mapId'], $worldPos[$s['guid']]['posX'], $worldPos[$s['guid']]['posY'], $s['type'], $s['guid'], $s['areaId'], $s['floor']);
|
||||
|
||||
if (isset($menu[$p['areaId']]))
|
||||
continue;
|
||||
else if ($p['areaId'] == $s['areaId'])
|
||||
$menu[$p['areaId']] = [$p['areaId'], '$g_zones['.$p['areaId'].']', '', null, ['class' => 'checked q0']];
|
||||
else
|
||||
$menu[$p['areaId']] = [$p['areaId'], '$g_zones['.$p['areaId'].']', '$spawnposfix.bind(null, '.self::$type.', '.$s['guid'].', '.$p['areaId'].', 0)', null, null];
|
||||
}
|
||||
|
||||
foreach ($floors as $area => $f)
|
||||
{
|
||||
$menu[$area][2] = '';
|
||||
$menu[$area][3] = [];
|
||||
if ($menu[$area][4])
|
||||
$menu[$area][4]['class'] = 'checked';
|
||||
|
||||
foreach ($f as $n)
|
||||
{
|
||||
if ($n == $s['floor'])
|
||||
$menu[$area][3][] = [$n, '$g_zone_areas['.$area.']['.($n - 1).']', '', null, ['class' => 'checked q0']];
|
||||
else
|
||||
$menu[$area][3][] = [$n, '$g_zone_areas['.$area.']['.($n - 1).']', '$spawnposfix.bind(null, '.self::$type.', '.$s['guid'].', '.$area.', '.$n.')'];
|
||||
}
|
||||
}
|
||||
|
||||
$menu = array_values($menu);
|
||||
}
|
||||
|
||||
if ($menu)
|
||||
{
|
||||
$footer = '<br /><span class="q2">Click to move displayed spawn point</span>';
|
||||
array_unshift($menu, [null, "Move to..."]);
|
||||
}
|
||||
}
|
||||
if ($menu)
|
||||
$footer = '<br /><span class="q2">Click to move pin</span>';
|
||||
}
|
||||
|
||||
if ($info)
|
||||
|
||||
@@ -257,6 +257,13 @@ define('GUIDE_STATUS_ARCHIVED', 5);
|
||||
|
||||
define('DEFAULT_ICON', 'inv_misc_questionmark');
|
||||
|
||||
define('MENU_IDX_ID', 0); // ID: A number or string; null makes the menu item a separator
|
||||
define('MENU_IDX_NAME', 1); // Name: A string
|
||||
define('MENU_IDX_URL', 2); // URL: A string for the URL, or a function to call when the menu item is clicked
|
||||
define('MENU_IDX_SUB', 3); // Submenu: Child menu
|
||||
define('MENU_IDX_OPT', 4); // Options: JSON array with additional options
|
||||
|
||||
|
||||
/*
|
||||
* Game
|
||||
*/
|
||||
|
||||
@@ -311,16 +311,27 @@ class Game
|
||||
switch ($type)
|
||||
{
|
||||
case Type::NPC:
|
||||
$result = DB::World()->select('SELECT `guid` AS ARRAY_KEY, `id`, `map` AS `mapId`, `position_x` AS `posX`, `position_y` AS `posY` FROM creature WHERE `guid` IN (?a)', $guids);
|
||||
$result = DB::World()->select('SELECT `guid` AS ARRAY_KEY, `id`, `map` AS `mapId`, `position_x` AS `posX`, `position_y` AS `posY` FROM creature WHERE `guid` IN (?a)', $guids);
|
||||
break;
|
||||
case Type::OBJECT:
|
||||
$result = DB::World()->select('SELECT `guid` AS ARRAY_KEY, `id`, `map` AS `mapId`, `position_x` AS `posX`, `position_y` AS `posY` FROM gameobject WHERE `guid` IN (?a)', $guids);
|
||||
$result = DB::World()->select('SELECT `guid` AS ARRAY_KEY, `id`, `map` AS `mapId`, `position_x` AS `posX`, `position_y` AS `posY` FROM gameobject WHERE `guid` IN (?a)', $guids);
|
||||
break;
|
||||
case Type::SOUND:
|
||||
$result = DB::AoWoW()->select('SELECT `id` AS ARRAY_KEY, `soundId` AS `id`, `mapId`, `posX`, `posY` FROM ?_soundemitters WHERE `id` IN (?a)', $guids);
|
||||
$result = DB::AoWoW()->select('SELECT `id` AS ARRAY_KEY, `soundId` AS `id`, `mapId`, `posX`, `posY` FROM ?_soundemitters WHERE `id` IN (?a)', $guids);
|
||||
break;
|
||||
case Type::ZONE:
|
||||
$result = DB::Aowow()->select('SELECT -`id` AS ARRAY_KEY, `id`, `parentMapId` AS `mapId`, `parentX` AS `posX`, `parentY` AS `posY` FROM ?_zones WHERE -`id` IN (?a)', $guids);
|
||||
break;
|
||||
case Type::AREATRIGGER:
|
||||
$result = DB::AoWoW()->select('SELECT `id` AS ARRAY_KEY, `id`, `mapId`, `posX`, `posY` FROM ?_areatrigger WHERE `id` IN (?a)', $guids);
|
||||
$result = [];
|
||||
if ($base = array_filter($guids, function ($x) { return $x > 0; }))
|
||||
$result = array_replace($result, DB::AoWoW()->select('SELECT `id` AS ARRAY_KEY, `id`, `mapId`, `posX`, `posY` FROM ?_areatrigger WHERE `id` IN (?a)', $base));
|
||||
if ($endpoints = array_filter($guids, function ($x) { return $x < 0; }))
|
||||
$result = array_replace($result, DB::World()->select(
|
||||
'SELECT -`ID` AS ARRAY_KEY, ID AS `id`, `target_map` AS `mapId`, `target_position_x` AS `posX`, `target_position_y` AS `posY` FROM areatrigger_teleport WHERE -`id` IN (?a) UNION
|
||||
SELECT -`entryorguid` AS ARRAY_KEY, entryorguid AS `id`, `action_param1` AS `mapId`, `target_x` AS `posX`, `target_y` AS `posY` FROM smart_scripts WHERE -`entryorguid` IN (?a) AND `source_type` = ?d AND `action_type` = ?d',
|
||||
$endpoints, $endpoints, SAI_SRC_TYPE_AREATRIGGER, SAI_ACTION_TELEPORT
|
||||
));
|
||||
break;
|
||||
default:
|
||||
trigger_error('Game::getWorldPosForGUID - instanced with unsupported TYPE #'.$type, E_USER_WARNING);
|
||||
|
||||
@@ -140,6 +140,7 @@ abstract class CLI
|
||||
private const CHR_ESC = 27;
|
||||
private const CHR_BACKSPACE = 127;
|
||||
|
||||
public const LOG_NONE = -1;
|
||||
public const LOG_BLANK = 0;
|
||||
public const LOG_ERROR = 1;
|
||||
public const LOG_WARN = 2;
|
||||
@@ -190,13 +191,13 @@ abstract class CLI
|
||||
}
|
||||
|
||||
if ($i || $headless)
|
||||
self::write(' '.implode(' ' . self::tblDelim(' ') . ' ', $row), -1, $timestamp);
|
||||
self::write(' '.implode(' ' . self::tblDelim(' ') . ' ', $row), CLI::LOG_NONE, $timestamp);
|
||||
else
|
||||
self::write(self::tblHead(' '.implode(' ', $row)), -1, $timestamp);
|
||||
self::write(self::tblHead(' '.implode(' ', $row)), CLI::LOG_NONE, $timestamp);
|
||||
}
|
||||
|
||||
if (!$headless)
|
||||
self::write(self::tblHead(str_pad('', array_sum($pads) + count($pads) * 3 - 2)), -1, $timestamp);
|
||||
self::write(self::tblHead(str_pad('', array_sum($pads) + count($pads) * 3 - 2)), CLI::LOG_NONE, $timestamp);
|
||||
|
||||
self::write();
|
||||
}
|
||||
@@ -1576,7 +1577,7 @@ abstract class Util
|
||||
}
|
||||
|
||||
// orientation is 2*M_PI for a full circle, increasing counterclockwise
|
||||
static function O2Deg($o)
|
||||
public static function O2Deg($o)
|
||||
{
|
||||
// orientation values can exceed boundaries (for whatever reason)
|
||||
while ($o < 0)
|
||||
@@ -1609,7 +1610,7 @@ abstract class Util
|
||||
return [(int)$deg, $desc];
|
||||
}
|
||||
|
||||
static function mask2bits(int $bitmask, int $offset = 0) : array
|
||||
public static function mask2bits(int $bitmask, int $offset = 0) : array
|
||||
{
|
||||
$bits = [];
|
||||
$i = 0;
|
||||
@@ -1625,6 +1626,46 @@ abstract class Util
|
||||
|
||||
return $bits;
|
||||
}
|
||||
|
||||
public static function buildPosFixMenu(int $mapId, float $posX, float $posY, int $type, int $guid, int $parentArea = 0, int $parentFloor = 0) : array
|
||||
{
|
||||
$points = Game::worldPosToZonePos($mapId, $posX, $posY);
|
||||
if (!$points || count($points) < 2)
|
||||
return [];
|
||||
|
||||
$floors = [];
|
||||
$menu = [[null, "Move Location to..."]];
|
||||
foreach ($points as $p)
|
||||
{
|
||||
if ($p['multifloor'])
|
||||
$floors[$p['areaId']][] = $p['floor'];
|
||||
|
||||
if (isset($menu[$p['areaId']]))
|
||||
continue;
|
||||
else if ($p['areaId'] == $parentArea)
|
||||
$menu[$p['areaId']] = [$p['areaId'], '$g_zones['.$p['areaId'].']', '', null, ['class' => 'checked q0']];
|
||||
else
|
||||
$menu[$p['areaId']] = [$p['areaId'], '$g_zones['.$p['areaId'].']', '$spawnposfix.bind(null, '.$type.', '.$guid.', '.$p['areaId'].', 0)', null, null];
|
||||
}
|
||||
|
||||
foreach ($floors as $area => $f)
|
||||
{
|
||||
$menu[$area][MENU_IDX_URL] = null;
|
||||
$menu[$area][MENU_IDX_SUB] = [];
|
||||
if ($menu[$area][MENU_IDX_OPT])
|
||||
$menu[$area][MENU_IDX_OPT]['class'] = 'checked';
|
||||
|
||||
foreach ($f as $n)
|
||||
{
|
||||
if ($n == $parentFloor)
|
||||
$menu[$area][MENU_IDX_SUB][] = [$n, '$g_zone_areas['.$area.']['.($n - 1).']', '', null, ['class' => 'checked q0']];
|
||||
else
|
||||
$menu[$area][MENU_IDX_SUB][] = [$n, '$g_zone_areas['.$area.']['.($n - 1).']', '$spawnposfix.bind(null, '.$type.', '.$guid.', '.$area.', '.$n.')'];
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($menu);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user