diff --git a/includes/types/basetype.class.php b/includes/types/basetype.class.php index c47eddf3..be9c6c95 100644 --- a/includes/types/basetype.class.php +++ b/includes/types/basetype.class.php @@ -599,18 +599,19 @@ trait spawnHelper } } - private function createFullSpawns() // for display on map (object/npc detail page) + // for display on map (object/npc detail page) + private function createFullSpawns(bool $skipWPs = false, bool $skipAdmin = false, bool $hasLabel = false, bool $hasLink = false) { $data = []; $wpSum = []; $wpIdx = 0; $worldPos = []; - $spawns = DB::Aowow()->select("SELECT * FROM ?_spawns WHERE `type` = ?d AND `typeId` = ?d AND `posX` > 0 AND `posY` > 0", self::$type, $this->id); + $spawns = DB::Aowow()->select("SELECT * FROM ?_spawns WHERE `type` = ?d AND `typeId` IN (?a) AND `posX` > 0 AND `posY` > 0", self::$type, $this->getFoundIDs()); if (!$spawns) return; - if (User::isInGroup(U_GROUP_MODERATOR)) + if (!$skipAdmin && User::isInGroup(U_GROUP_MODERATOR)) if ($guids = array_column(array_filter($spawns, fn($x) => $x['guid'] > 0 || $x['type'] != Type::NPC), 'guid')) $worldPos = WorldPosition::getForGUID(self::$type, ...$guids); @@ -620,7 +621,7 @@ trait spawnHelper // 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 && $s['type'] == Type::NPC) + if (!$skipWPs && 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'])) { @@ -661,7 +662,7 @@ trait spawnHelper $opts['type'] = 4; // make pip purple } - if (User::isInGroup(U_GROUP_STAFF)) + if (!$skipAdmin && User::isInGroup(U_GROUP_STAFF)) { if ($isAccessory) $info[0] = 'Vehicle Accessory'; @@ -706,14 +707,28 @@ trait spawnHelper $footer = '
Click to move pin'; } + /* recognized opts + * url: string - makes pin clickable + * tooltip: array - title => [info: lines, footer: line] + * label: string - single line tooltip (skipped if 'tooltip' is set) + * menu: array - menu definiton (conflicts with url) + * type: int - colors the pip [default, green, red, blue, purple] + * lines: array - [[destX, destY]] - draws line from point to dest + */ + if ($info) $tt['info'] = $info; if ($footer) $tt['footer'] = $footer; - if ($tt) + if ($tt && $this->getEntry($s['typeId'])) $opts['tooltip'] = [$this->getField('name', true) => $tt]; + else if ($hasLabel && $this->getEntry($s['typeId'])) + $opts['label'] = $this->getField('name', true); + + if ($hasLink) + $opts['url'] = '?' . Type::getFileString(self::$type) . '=' . $s['typeId']; if ($menu) $opts['menu'] = $menu; @@ -722,9 +737,9 @@ trait spawnHelper } foreach ($data as $a => &$areas) foreach ($areas as $f => &$floor) - $floor['count'] = count($floor['coords']) - (!empty($wpSum[$a][$f]) ? $wpSum[$a][$f] : 0); + $floor['count'] = count($floor['coords']) - ($wpSum[$a][$f] ?? 0); - uasort($data, array($this, 'sortBySpawnCount')); + uasort($data, [$this, 'sortBySpawnCount']); $this->spawnResult[SPAWNINFO_FULL] = $data; } @@ -733,11 +748,7 @@ trait spawnHelper $aCount = current($a)['count']; $bCount = current($b)['count']; - if ($aCount == $bCount) { - return 0; - } - - return ($aCount < $bCount) ? 1 : -1; + return $bCount <=> $aCount; // sort descending } private function createZoneSpawns() // [zoneId1, zoneId2, ..] for locations-column in listview @@ -785,7 +796,7 @@ trait spawnHelper $this->spawnResult[SPAWNINFO_QUEST] = $spawns; } - public function getSpawns($mode) + public function getSpawns(int $mode, bool ...$info) { // only Creatures, GOs and SoundEmitters can be spawned if (!self::$type || !$this->getfoundIDs() || (self::$type != Type::NPC && self::$type != Type::OBJECT && self::$type != Type::SOUND && self::$type != Type::AREATRIGGER)) @@ -800,7 +811,7 @@ trait spawnHelper return $this->spawnResult[SPAWNINFO_SHORT]; case SPAWNINFO_FULL: if (empty($this->spawnResult[SPAWNINFO_FULL])) - $this->createFullSpawns(); + $this->createFullSpawns(...$info); return $this->spawnResult[SPAWNINFO_FULL]; case SPAWNINFO_ZONES: diff --git a/localization/locale_dede.php b/localization/locale_dede.php index fb3b43af..a7ec2b48 100644 --- a/localization/locale_dede.php +++ b/localization/locale_dede.php @@ -2081,6 +2081,8 @@ $lang = array( 'uniqueEquipped'=> ["Einzigartig anlegbar", null, "Einzigartig angelegt: %s (%d)"], 'speed' => "Tempo", 'dps' => "(%.1f Schaden pro Sekunde)", + 'vendorIn' => "Händlerstandpunkte", + 'purchasedIn' => "Dieser Gegenstand kann gekauft werden in", 'duration' => array( // ITEM_DURATION_* '', "Dauer: %d Sek.", diff --git a/localization/locale_enus.php b/localization/locale_enus.php index 67d56ebc..c50ddd24 100644 --- a/localization/locale_enus.php +++ b/localization/locale_enus.php @@ -2081,6 +2081,8 @@ $lang = array( 'uniqueEquipped'=> ["Unique-Equipped", null, "Unique-Equipped: %s (%d)"], // ITEM_UNIQUE_EQUIPPABLE, null, ITEM_LIMIT_CATEGORY_MULTIPLE 'speed' => "Speed", // SPEED 'dps' => "(%.1f damage per second)", // DPS_TEMPLATE + 'vendorIn' => "Vendor Locations", + 'purchasedIn' => "This item can be purchased in", 'duration' => array( // ITEM_DURATION_* '', "Duration: %d sec", diff --git a/localization/locale_eses.php b/localization/locale_eses.php index 49b06015..e3d9fc02 100644 --- a/localization/locale_eses.php +++ b/localization/locale_eses.php @@ -2081,6 +2081,8 @@ $lang = array( 'uniqueEquipped'=> ["Único-Equipado", null, "Único-Equipado: %s (%d)"], 'speed' => "Veloc.", 'dps' => "(%.1f daño por segundo)", + 'vendorIn' => "Ubicación de Vendedores", + 'purchasedIn' => "[This item can be purchased in]", 'duration' => array( '', "Duración: %d s", diff --git a/localization/locale_frfr.php b/localization/locale_frfr.php index 8cbf0404..1c7845b2 100644 --- a/localization/locale_frfr.php +++ b/localization/locale_frfr.php @@ -2081,6 +2081,8 @@ $lang = array( 'uniqueEquipped'=> ["Unique - Equipé", null, "Unique - Equipé: %s (%d)"], // ITEM_UNIQUE_EQUIPPABLE, null, ITEM_LIMIT_CATEGORY_MULTIPLE 'speed' => "Vitesse", 'dps' => "(%.1f dégâts par seconde)", + 'vendorIn' => "Lieux de vente", + 'purchasedIn' => "Cet objet peut être acheté dans", 'duration' => array( '', "Durée : %d sec", diff --git a/localization/locale_ruru.php b/localization/locale_ruru.php index 79dad67e..8f1d8a5d 100644 --- a/localization/locale_ruru.php +++ b/localization/locale_ruru.php @@ -2081,6 +2081,8 @@ $lang = array( 'uniqueEquipped'=> ["Уникальный использующийся", null, "Уникальный использующийся предмет: %s (%d)"], 'speed' => "Скорость", 'dps' => "(%.1f ед. урона в секунду)", + 'vendorIn' => "Расположение торговца", + 'purchasedIn' => "Этот предмет приобретается в", 'duration' => array( '', "Срок действия: %d |4секунда:секунды:секунд;", diff --git a/localization/locale_zhcn.php b/localization/locale_zhcn.php index e877b495..2cb39fff 100644 --- a/localization/locale_zhcn.php +++ b/localization/locale_zhcn.php @@ -2081,6 +2081,8 @@ $lang = array( 'uniqueEquipped'=> ["装备唯一", null, "装备唯一:%s (%d)"], 'speed' => "速度", 'dps' => "(每秒伤害%.1f)", + 'vendorIn' => "[Vendor Locations]", + 'purchasedIn' => "[This item can be purchased in]", 'duration' => array( '', "持续时间:%d秒", diff --git a/pages/areatrigger.php b/pages/areatrigger.php index 1bd29174..8bf4d3e2 100644 --- a/pages/areatrigger.php +++ b/pages/areatrigger.php @@ -58,7 +58,7 @@ class AreaTriggerPage extends GenericPage $map = null; if ($spawns = $this->subject->getSpawns(SPAWNINFO_FULL)) { - $map = ['data' => ['parent' => 'mapper-generic'], 'mapperData' => &$spawns]; + $map = ['data' => ['parent' => 'mapper-generic'], 'mapperData' => &$spawns, 'foundIn' => Lang::areatrigger('foundIn')]; foreach ($spawns as $areaId => &$areaData) $map['extra'][$areaId] = ZoneList::getName($areaId); } diff --git a/pages/item.php b/pages/item.php index 121aa130..646b66fb 100644 --- a/pages/item.php +++ b/pages/item.php @@ -783,6 +783,14 @@ class ItemPage extends genericPage $soldBy = new CreatureList(array(['id', array_keys($vendors)])); if (!$soldBy->error) { + // show mapper for vendors + if ($vendorSpawns = $soldBy->getSpawns(SPAWNINFO_FULL, true, true, true, true)) + { + $this->map = ['data' => ['parent' => 'mapper-generic'], 'mapperData' => &$vendorSpawns, 'foundIn' => Lang::item('purchasedIn')]; + foreach ($vendorSpawns as $areaId => $_) + $this->map['extra'][$areaId] = ZoneList::getName($areaId); + } + $sbData = $soldBy->getListviewData(); $this->extendGlobalData($soldBy->getJSGlobals(GLOBALINFO_SELF)); diff --git a/pages/npc.php b/pages/npc.php index d52677ce..d8f91a69 100644 --- a/pages/npc.php +++ b/pages/npc.php @@ -371,7 +371,7 @@ class NpcPage extends GenericPage $map = null; if ($spawns = $this->subject->getSpawns(SPAWNINFO_FULL)) { - $map = ['data' => ['parent' => 'mapper-generic'], 'mapperData' => &$spawns]; + $map = ['data' => ['parent' => 'mapper-generic'], 'mapperData' => &$spawns, 'foundIn' => Lang::npc('foundIn')]; foreach ($spawns as $areaId => &$areaData) $map['extra'][$areaId] = ZoneList::getName($areaId); } diff --git a/pages/object.php b/pages/object.php index ee42121d..8abc3f31 100644 --- a/pages/object.php +++ b/pages/object.php @@ -222,7 +222,7 @@ class ObjectPage extends GenericPage $map = null; if ($spawns = $this->subject->getSpawns(SPAWNINFO_FULL)) { - $map = ['data' => ['parent' => 'mapper-generic'], 'mapperData' => &$spawns]; + $map = ['data' => ['parent' => 'mapper-generic'], 'mapperData' => &$spawns, 'foundIn' => Lang::gameObject('foundIn')]; foreach ($spawns as $areaId => &$areaData) $map['extra'][$areaId] = ZoneList::getName($areaId); } diff --git a/pages/sound.php b/pages/sound.php index d1cb536d..c90a0a69 100644 --- a/pages/sound.php +++ b/pages/sound.php @@ -87,7 +87,7 @@ class SoundPage extends GenericPage $map = null; if ($spawns = $this->subject->getSpawns(SPAWNINFO_FULL)) { - $map = ['data' => ['parent' => 'mapper-generic'], 'mapperData' => &$spawns]; + $map = ['data' => ['parent' => 'mapper-generic'], 'mapperData' => &$spawns, 'foundIn' => Lang::sound('foundIn')]; foreach ($spawns as $areaId => &$areaData) $map['extra'][$areaId] = ZoneList::getName($areaId); } diff --git a/template/bricks/mapper.tpl.php b/template/bricks/mapper.tpl.php index 51814344..50e89719 100644 --- a/template/bricks/mapper.tpl.php +++ b/template/bricks/mapper.tpl.php @@ -6,26 +6,15 @@ if (isset($this->map) && empty($this->map)): elseif (!empty($this->map['data'])): if ($this->type == Type::QUEST) : echo "
\n"; - elseif ($this->type != Type::ZONE): + elseif ($this->map['mapperData']): echo '
'; - if ($this->type == Type::OBJECT): - echo Lang::gameObject('foundIn'); - elseif ($this->type == Type::SOUND): - echo Lang::sound('foundIn'); - elseif ($this->type == Type::NPC): - echo Lang::npc('foundIn'); - elseif ($this->type == Type::AREATRIGGER): - echo Lang::areatrigger('foundIn'); - else: - echo "UNKNOWN TYPE"; - endif; + echo $this->map['foundIn']; echo ' '; - $extra = $this->map['extra']; - echo Lang::concat($this->map['mapperData'], true, function ($areaData, $areaId) use ($extra) { - return ''.$extra[$areaId].' ('.array_sum(array_column($areaData, 'count')).')'; + echo Lang::concat($this->map['mapperData'], true, function ($areaData, $areaId) { + return ''.$this->map['extra'][$areaId].' ('.array_sum(array_column($areaData, 'count')).')'; }); echo ".
\n"; diff --git a/template/pages/item.tpl.php b/template/pages/item.tpl.php index 6e0f549c..8bc7d256 100644 --- a/template/pages/item.tpl.php +++ b/template/pages/item.tpl.php @@ -31,6 +31,11 @@ endif; $this->brick('article'); +if (isset($this->map)): + echo "

".Lang::item('vendorIn')."

\n"; + $this->brick('mapper'); +endif; + if (!empty($this->transfer)): echo "
\n ".$this->transfer."\n"; endif;