- implemented display of spawns and waypoints for gameobjects and creatures

!IMPORTANT!
  Due to the inability to determine what layer covers what height-level
  in multilayer-zones, spawns and waypoints WILL have duplicates and must
  be removed manually from ?_spawns and ?_waypoints respectively, if
  nessecary. Besides, the other points may also need manual love.
- NPC:
  * removed a redundant cuFlags for Bosses
  * set NPC_CU_INSTANCE_BOSS with data from world.instance_encounters
  * removed misc. factions from tooltip
  * fixed malformed condition for creature-loot
  * location is displayed in Listviews (also for GOs)
  * enabled filters foundIn and relatedEvent (also for GOs)
  * do not display empty quotes
- Zone:
  * initial implementation of detail page
- Misc:
  * fixed notices being displayed without restrictions
  * added RewriteBase hint to .htaccess (lost several hours to this one)
  * removed lost isles from dataset 'zones'
  * updated sql-archives and removed old sql updates, db_setup_2.zip
    will need to be reapplied
This commit is contained in:
Sarjuuk
2014-10-02 19:50:31 +02:00
parent 0806e616ae
commit 43fe5e4b4d
39 changed files with 934 additions and 40572 deletions

View File

@@ -1,5 +1,5 @@
Order Deny,Allow
<FilesMatch "\.(conf|php|tpl|in)$">
<FilesMatch "\.(conf|php|in)$">
Deny from all
</FilesMatch>
<FilesMatch "^(index)\.php$">
@@ -20,9 +20,10 @@ AddDefaultCharset utf8
php_value default_charset UTF-8
RewriteEngine on
# RewriteBase /~user/localPath/ # enable if the rules do not work, when they should
# Mapper-Helper: If you cant provide maps for all locales, redirect the browser
RewriteRule ^(.*/?)static/images/wow/maps/(frfr|dede|eses|ruru)/(.*)$ $1static/images/wow/maps/enus/$3 [NC]
RewriteRule ^(.*/?)static/images/wow/maps/(frfr|dede|eses|ruru)/(.*)$ $1static/images/wow/maps/enus/$3 [NC]
# accept flattened urls | NYI - need more work :x
# RewriteRule ^([a-z0-9\-]+)$ ?$1 [NC] # /items => ?items

View File

@@ -36,7 +36,6 @@ Mapper.multiLevelZones = {
4395: ['4395-1', '4395-2'],
4494: ['4494-1', '4494-2'],
4714: ['4714-1', '4714_1', '4714_2', '4714_3'],
4720: ['4720_1', '4720_2', '4720_3'],
4722: ['4722-1', '4722-2'],
4723: ['4723-1', '4723-2'],
4812: ['4812-1', '4812-2', '4812-3', '4812-4', '4812-5', '4812-6', '4812-7', '4812-8'],

View File

@@ -224,7 +224,6 @@ define('OBJECT_CU_NOT_PERSISTANT', 0x80);
define('NPC_CU_INSTANCE_BOSS', 0x01);
define('NPC_CU_DIFFICULTY_DUMMY', 0x02);
define('NPC_CU_DUNGEON_ENCOUNTER', 0x04);
define('ITEM_CU_OT_ITEMLOOT', 0x01); // there are no sourceTypes for these two cases
define('ITEM_CU_OT_OBJECTLOOT', 0x02);

View File

@@ -501,61 +501,137 @@ trait listviewHelper
}
/*
!IMPORTANT!
It is flat out impossible to distinguish between floors for multi-level areas, if the floors overlap each other!
The coordinates generated by the script WILL be on every level and will have to be removed MANUALLY!
impossible := you are not keen on reading wmo-data;
*/
trait spawnHelper
{
private static $spawnQuery = " SELECT a.guid AS ARRAY_KEY, map, position_x, position_y, spawnMask, phaseMask, spawntimesecs, eventEntry, pool_entry AS pool FROM ?# a LEFT JOIN ?# b ON a.guid = b.guid LEFT JOIN ?# c ON a.guid = c.guid WHERE id = ?d";
private function fetch()
{
if (!$this->id)
return false;
switch (get_class($this))
{
case 'CreatureList':
return DB::Aowow()->select(self::$spawnQuery, 'creature', 'game_event_creature', 'pool_creature', $this->id);
case 'GameObjectList':
return DB::Aowow()->select(self::$spawnQuery, 'gameobject', 'game_event_gameobject', 'pool_gameobject', $this->id);
default:
return false;
}
}
private $spawnResult = array(
SPAWNINFO_FULL => null,
SPAWNINFO_SHORT => null,
SPAWNINFO_ZONES => null
);
/*
todo (med): implement this alpha-map-check-virtual-map-transform-wahey!
note: map in tooltips is activated by either '#map' as anchor (will automatic open mapviewer, when clicking link) in the href or as parameterless rel-parameter e.g. rel="map" in the anchor
*/
public function getSpawns($spawnInfo)
private function createShortSpawns() // [zoneId, [[x1, y1], [x2, y2], ..]] as tooltip2 if enabled by <a rel="map" ...> (one area, one floor, one craeture, no survivor)
{
// SPAWNINFO_SHORT: true => only the most populated area and only coordinates
$data = [];
$this->spawnResult[SPAWNINFO_SHORT] = null; // NYI
}
// $raw = $this->fetch();
// if (!$raw)
// return [];
private function createFullSpawns() // for display on map (objsct/npc detail page)
{
$data = [];
$wpIdx = 0;
$spawns = DB::Aowow()->select("SELECT * FROM ?_spawns WHERE type = ?d AND typeId = ?d", self::$type, $this->id);
if (!$spawns)
return;
/*
SPAWNINFO_FULL:
$data = array(
areaId => array(
floorNo => array (
posX =>
posY =>
respawn =>
phaseMask =>
spawnMask =>
eventId =>
poolId =>
)
)
)
foreach ($spawns as $s)
{
// 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
if (count($spawns) < 6 && self::$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']))
{
foreach ($wPoints as $i => $p)
{
$label = [Lang::$npc['waypoint'].Lang::$main['colon'].$p['point']];
SPAWNINFO_SHORT: [zoneId, [[x1, y1], [x2, y2], ..]] // only the most populated zone
if ($p['wait'])
$label[] = Lang::$npc['wait'].Lang::$main['colon'].Util::formatTime($p['wait'], false);
SPAWNINFO_ZONES: [zoneId1, zoneId2, ..] // only zones
*/
$set = ['label' => '$<br><span class="q0">'.implode('<br>', $label).'</span>', 'type' => $wpIdx];
return $data;
// connective line
if ($i > 0)
$set['lines'] = [[$wPoints[$i - 1]['posX'], $wPoints[$i - 1]['posY']]];
$data[$s['areaId']][$s['floor']]['coords'][] = [$p['posX'], $p['posY'], $set];
}
$wpIdx++;
}
}
$label = [];
if (User::isInGroup(U_GROUP_STAFF))
$label[] = 'GUID'.Lang::$main['colon'].$s['guid'];
if ($_ = Util::formatTime($s['respawn'] * 1000, false))
$label[] = Lang::$npc['respawnIn'].Lang::$main['colon'].$_;
if (User::isInGroup(U_GROUP_STAFF))
{
if ($s['phaseMask'] > 1)
$label[] = Lang::$game['phases'].Lang::$main['colon'].$s['phaseMask'];
if ($s['spawnMask'] == 15)
$label[] = Lang::$game['mode'].Lang::$main['colon'].Lang::$game['modes'][-1];
else if ($s['spawnMask'])
{
$_ = [];
for ($i = 0; $i < 4; $i++)
if ($s['spawnMask'] & 1 << $i)
$_[] = Lang::$game['modes'][$i];
$label[] = Lang::$game['mode'].Lang::$main['colon'].implode(', ', $_);
}
}
$data[$s['areaId']] [$s['floor']] ['coords'] [] = [$s['posX'], $s['posY'], ['label' => '$<br><span class="q0">'.implode('<br>', $label).'</span>']];
}
$this->spawnResult[SPAWNINFO_FULL] = $data;
}
private function createZoneSpawns() // [zoneId1, zoneId2, ..] for locations-column in listview
{
$res = DB::Aowow()->selectCol("SELECT typeId AS ARRAY_KEY, GROUP_CONCAT(DISTINCT areaId) FROM ?_spawns WHERE type = ?d AND typeId IN (?a) GROUP BY typeId", self::$type, $this->getfoundIDs());
foreach ($res as &$r)
{
$r = explode(',', $r);
if (count($r) > 3)
array_splice($r, 3, count($r), -1);
}
$this->spawnResult[SPAWNINFO_ZONES] = $res;
}
public function getSpawns($mode)
{
// ony Creatures and GOs can be spawned
if (!self::$type && self::$type != TYPE_NPC && self::$type != TYPE_OBJECT)
return [];
switch ($mode)
{
case SPAWNINFO_SHORT:
if (empty($this->spawnResult[SPAWNINFO_SHORT]))
$this->createShortSpawns();
return $this->spawnResult[SPAWNINFO_SHORT];
case SPAWNINFO_FULL:
if (empty($this->spawnResult[SPAWNINFO_FULL]))
$this->createFullSpawns();
return $this->spawnResult[SPAWNINFO_FULL];
case SPAWNINFO_ZONES:
if (empty($this->spawnResult[SPAWNINFO_ZONES]))
$this->createZoneSpawns();
return !empty($this->spawnResult[SPAWNINFO_ZONES][$this->id]) ? $this->spawnResult[SPAWNINFO_ZONES][$this->id] : [];
}
return [];
}
}
@@ -942,9 +1018,9 @@ abstract class Filter
if (is_bool($value))
return [$field, 0, ($value ? '>' : '<=')];
else if ($value == FILTER_ENUM_ANY) // any
return [$field, 0, '>'];
return [$field, 0, '!'];
else if ($value == FILTER_ENUM_NONE) // none
return [$field, 0, '<='];
return [$field, 0];
else if ($value !== null)
return [$field, $value];

View File

@@ -19,7 +19,8 @@ class CreatureList extends BaseType
'clsMax' => ['j' => 'creature_classlevelstats clsMax ON ct.unitClass = clsMax.class AND ct.maxLevel = clsMax.level', 's' => ', clsMax.attackpower AS mleAtkPwrMax, clsMax.rangedattackpower AS rngAtkPwrMax, clsMax.baseArmor * ct.armorMod AS armorMax, (CASE ct.exp WHEN 0 THEN clsMin.damage_base WHEN 1 THEN clsMin.damage_exp1 ELSE clsMin.damage_exp2 END) * ct.dmgMultiplier AS dmgMax, (CASE ct.exp WHEN 0 THEN clsMax.basehp0 WHEN 1 THEN clsMax.basehp1 ELSE clsMax.basehp2 END) * ct.healthMod AS healthMax, clsMax.baseMana * ct.manaMod AS manaMax'],
'qse' => ['j' => ['?_quests_startend qse ON qse.type = 1 AND qse.typeId = ct.id', true], 's' => ', IF(min(qse.method) = 1 OR max(qse.method) = 3, 1, 0) AS startsQuests, IF(min(qse.method) = 2 OR max(qse.method) = 3, 1, 0) AS endsQuests', 'g' => 'ct.id'],
'qt' => ['j' => '?_quests qt ON qse.questId = qt.id'],
'rep' => ['j' => ['creature_onkill_reputation rep ON rep.creature_id = ct.id', true]]
'rep' => ['j' => ['creature_onkill_reputation rep ON rep.creature_id = ct.id', true]],
's' => ['j' => '?_spawns s ON s.type = 1 AND s.typeId = ct.id']
);
public static function getName($id)
@@ -77,9 +78,9 @@ class CreatureList extends BaseType
if ($type == 1 && $fam) // 1: Beast
$x .= '<tr><td>'.Lang::$game['fa'][$fam].'</td></tr>';
// todo (low): exclude not displayed factions
if ($f = FactionList::getName($this->getField('factionId')))
$x .= '<tr><td>'.$f.'</td></tr>';
$fac = new FactionList(array([['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0], ['id', (int)$this->getField('factionId')]));
if (!$fac->error)
$x .= '<tr><td>'.$fac->getField('name', true).'</td></tr>';
$x .= '</table>';
@@ -139,6 +140,11 @@ class CreatureList extends BaseType
}
}
public function isBoss()
{
return ($this->curTpl['cuFlags'] & NPC_CU_INSTANCE_BOSS) || ($this->curTpl['typeFlags'] & 0x4 && $this->curTpl['rank']);
}
public function getListviewData($addInfoMask = 0x0)
{
/* looks like this data differs per occasion
@@ -183,7 +189,7 @@ class CreatureList extends BaseType
'minlevel' => $this->curTpl['minLevel'],
'maxlevel' => $this->curTpl['maxLevel'],
'id' => $this->id,
'boss' => $this->curTpl['typeFlags'] & 0x4 && $this->curTpl['rank'] ? 1 : 0,
'boss' => $this->isBoss() ? 1 : 0,
'classification' => $this->curTpl['rank'],
'location' => $this->getSpawns(SPAWNINFO_ZONES),
'name' => $this->getField('name', true),
@@ -252,8 +258,9 @@ class CreatureListFilter extends Filter
// cr => [type, field, misc, extraCol]
protected $genericFilter = array( // misc (bool): _NUMERIC => useFloat; _STRING => localized; _FLAG => match Value; _BOOLEAN => stringSet
5 => [FILTER_CR_FLAG, 'npcflag', NPC_FLAG_REPAIRER ], // canrepair
9 => [FILTER_CR_BOOLEAN, 'lootId', ], // lootable
5 => [FILTER_CR_FLAG, 'npcflag', NPC_FLAG_REPAIRER ], // canrepair
6 => [FILTER_CR_ENUM, 's.areaId', null ], // foundin
9 => [FILTER_CR_BOOLEAN, 'lootId', ], // lootable
11 => [FILTER_CR_BOOLEAN, 'pickpocketLootId', ], // pickpocketable
18 => [FILTER_CR_FLAG, 'npcflag', NPC_FLAG_AUCTIONEER ], // auctioneer
19 => [FILTER_CR_FLAG, 'npcflag', NPC_FLAG_BANKER ], // banker
@@ -384,6 +391,27 @@ class CreatureListFilter extends Filter
return ['faction', $facTpls];
}
break;
case 38; // relatedevent
if (!$this->isSaneNumeric($cr[1]))
break;
if ($cr[1] == FILTER_ENUM_ANY)
{
$cGuids = DB::Aowow()->selectCol('SELECT DISTINCT gec.guid FROM game_event_creature gec JOIN ?_events e ON e.id = ABS(gec.eventEntry) WHERE e.holidayId <> 0');
return ['s.guid', $cGuids];
}
else if ($cr[1] == FILTER_ENUM_NONE)
{
$cGuids = DB::Aowow()->selectCol('SELECT DISTINCT gec.guid FROM game_event_creature gec JOIN ?_events e ON e.id = ABS(gec.eventEntry) WHERE e.holidayId <> 0');
return ['s.guid', $cGuids, '!'];
}
else if ($cr[1])
{
$cGuids = DB::Aowow()->selectCol('SELECT DISTINCT gec.guid FROM game_event_creature gec JOIN ?_events e ON e.id = ABS(gec.eventEntry) WHERE e.holidayId = ?d', $cr[1]);
return ['s.guid', $cGuids];
}
break;
case 42: // increasesrepwith [enum]
if (in_array($cr[1], $this->enums[3])) // reuse
@@ -436,8 +464,6 @@ class CreatureListFilter extends Filter
return ['OR', ['skinLootId', 0], [['typeFlags', NPC_TYPEFLAG_SPECIALLOOT, '&'], 0, '!']];
}
break;
case 6: // foundin [enum]
case 38: // relatedevent [enum]
case 34: // usemodel [str] // displayId -> id:creatureDisplayInfo.dbc/model -> id:cratureModelData.dbc/modelPath
case 41: // haslocation [yn] [staff]
/* todo */ return [1];

View File

@@ -16,7 +16,8 @@ class GameObjectList extends BaseType
'o' => [['ft', 'qse']],
'ft' => ['j' => ['?_factiontemplate ft ON ft.id = o.faction', true], 's' => ', ft.factionId, ft.A, ft.H'],
'qse' => ['j' => ['?_quests_startend qse ON qse.type = 2 AND qse.typeId = o.id', true], 's' => ', IF(min(qse.method) = 1 OR max(qse.method) = 3, 1, 0) AS startsQuests, IF(min(qse.method) = 2 OR max(qse.method) = 3, 1, 0) AS endsQuests', 'g' => 'o.id'],
'qt' => ['j' => '?_quests qt ON qse.questId = qt.id']
'qt' => ['j' => '?_quests qt ON qse.questId = qt.id'],
's' => ['j' => '?_spawns s ON s.type = 2 AND s.typeId = o.id']
);
public function __construct($conditions = [], $miscData = null)
@@ -79,9 +80,10 @@ class GameObjectList extends BaseType
foreach ($this->iterate() as $__)
{
$data[$this->id] = array(
'id' => $this->id,
'name' => $this->getField('name', true),
'type' => $this->curTpl['typeCat']
'id' => $this->id,
'name' => $this->getField('name', true),
'type' => $this->curTpl['typeCat'],
'location' => $this->getSpawns(SPAWNINFO_ZONES)
);
if (!empty($this->curTpl['reqSkill']))
@@ -150,18 +152,14 @@ class GameObjectListFilter extends Filter
public $extraOpts = [];
protected $genericFilter = array(
15 => [FILTER_CR_NUMERIC, 'id', null ], // id
1 => [FILTER_CR_ENUM, 's.areaId', null ], // foundin
7 => [FILTER_CR_NUMERIC, 'reqSkill', null ], // requiredskilllevel
13 => [FILTER_CR_FLAG, 'cuFlags', CUSTOM_HAS_COMMENT ], // hascomments
11 => [FILTER_CR_FLAG, 'cuFlags', CUSTOM_HAS_SCREENSHOT], // hasscreenshots
13 => [FILTER_CR_FLAG, 'cuFlags', CUSTOM_HAS_COMMENT ], // hascomments
15 => [FILTER_CR_NUMERIC, 'id', null ], // id
18 => [FILTER_CR_FLAG, 'cuFlags', CUSTOM_HAS_VIDEO ], // hasvideos
);
/*
{ id: 1, name: 'foundin', type: 'zone' },
{ id: 16, name: 'relatedevent', type: 'event-any+none' },
*/
protected function createSQLForCriterium(&$cr)
{
if (in_array($cr[0], array_keys($this->genericFilter)))
@@ -217,6 +215,27 @@ class GameObjectListFilter extends Filter
$this->extraOpts['o']['h'][] = 'endsQuests = 0';
return [1];
}
break;
case 16; // relatedevent
if (!$this->isSaneNumeric($cr[1]))
break;
if ($cr[1] == FILTER_ENUM_ANY)
{
$goGuids = DB::Aowow()->selectCol('SELECT DISTINCT geo.guid FROM game_event_gameobject geo JOIN ?_events e ON e.id = ABS(geo.eventEntry) WHERE e.holidayId <> 0');
return ['s.guid', $goGuids];
}
else if ($cr[1] == FILTER_ENUM_NONE)
{
$goGuids = DB::Aowow()->selectCol('SELECT DISTINCT geo.guid FROM game_event_gameobject geo JOIN ?_events e ON e.id = ABS(geo.eventEntry) WHERE e.holidayId <> 0');
return ['s.guid', $goGuids, '!'];
}
else if ($cr[1])
{
$goGuids = DB::Aowow()->selectCol('SELECT DISTINCT geo.guid FROM game_event_gameobject geo JOIN ?_events e ON e.id = ABS(geo.eventEntry) WHERE e.holidayId = ?d', $cr[1]);
return ['s.guid', $goGuids];
}
break;
}

View File

@@ -50,9 +50,10 @@ class SpellList extends BaseType
private $interactive = false;
private $charLevel = MAX_LEVEL;
protected $queryBase = 'SELECT s.*, id AS ARRAY_KEY FROM ?_spell s';
protected $queryBase = 'SELECT s.*, s.id AS ARRAY_KEY FROM ?_spell s';
protected $queryOpts = array(
's' => [['src']], // 6: TYPE_SPELL
's' => [['src', 'sr']], // 6: TYPE_SPELL
'sr' => ['j' => ['?_spellrange sr ON sr.id = s.rangeId'], 's' => ', sr.rangeMinHostile, sr.rangeMinFriend, sr.rangeMaxHostile, sr.rangeMaxFriend, sr.name_loc0 AS rangeText_loc0, sr.name_loc2 AS rangeText_loc2, sr.name_loc3 AS rangeText_loc3, sr.name_loc6 AS rangeText_loc6, sr.name_loc8 AS rangeText_loc8'],
'src' => ['j' => ['?_source src ON type = 6 AND typeId = s.id', true], 's' => ', src1, src2, src3, src4, src5, src6, src7, src8, src9, src10, src11, src12, src13, src14, src15, src16, src17, src18, src19, src20, src21, src22, src23, src24']
);

View File

@@ -4,11 +4,6 @@ if (!defined('AOWOW_REVISION'))
die('illegal access');
/*
areatable: discarded Ids
unused: 276, 296, 1579, 2280, 3459, 3817, 208, 4076
*/
class ZoneList extends BaseType
{
public static $type = TYPE_ZONE;
@@ -16,96 +11,25 @@ class ZoneList extends BaseType
protected $queryBase = 'SELECT *, id AS ARRAY_KEY FROM ?_zones z';
// use if you JUST need the name
public static function getName($id)
{
$n = DB::Aowow()->selectRow('
SELECT
name_loc0, name_loc2, name_loc3, name_loc6, name_loc8
FROM
?_zones
WHERE
id = ?d',
$id
);
return Util::localizedString($n, 'name');
}
public function getListviewData()
{
$data = [];
/*
UPDATE dbc.worldmaparea a, world.?_zones z SET yMax = `left`, xMax = top, yMin = `right`, xMin = bottom WHERE a.areaId = z.id;
LFG_TYPE_NONE = 0, // Internal use only
LFG_TYPE_DUNGEON = 1,
LFG_TYPE_RAID = 2,
LFG_TYPE_QUEST = 3,
LFG_TYPE_ZONE = 4,
LFG_TYPE_HEROIC = 5,
LFG_TYPE_RANDOM = 6
CREATE TABLE `aowow_zones` (
`id` MEDIUMINT(8) UNSIGNED NOT NULL COMMENT 'Zone Id',
`mapId` MEDIUMINT(8) UNSIGNED NOT NULL COMMENT 'Map Identifier',
`mapIdBak` MEDIUMINT(8) UNSIGNED NOT NULL,
`parentArea` MEDIUMINT(8) UNSIGNED NOT NULL,
`category` SMALLINT(6) NOT NULL,
`flags` INT(11) NOT NULL,
`cuFlags` INT(10) UNSIGNED NOT NULL,
`faction` TINYINT(2) NOT NULL,
`expansion` TINYINT(2) NOT NULL,
`type` TINYINT(2) UNSIGNED NOT NULL,
`areaType` TINYINT(2) UNSIGNED NOT NULL,
`xMin` FLOAT NOT NULL,
`xMax` FLOAT NOT NULL,
`yMin` FLOAT NOT NULL,
`yMax` FLOAT NOT NULL,
`maxPlayer` SMALLINT(6) NOT NULL,
`levelReq` SMALLINT(6) NOT NULL,
`levelReqLFG` SMALLINT(6) NOT NULL,
`levelHeroic` SMALLINT(6) NOT NULL,
`levelMax` SMALLINT(6) NOT NULL,
`levelMin` SMALLINT(6) NOT NULL,
`name_loc0` VARCHAR(255) NOT NULL COMMENT 'Map Name',
`name_loc2` VARCHAR(255) NOT NULL,
`name_loc3` VARCHAR(255) NOT NULL,
`name_loc6` VARCHAR(255) NOT NULL,
`name_loc8` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM;
var g_zone_categories = {
0: "Eastern Kingdoms", // areaTable.map == 0 AND
1: "Kalimdor", // areaTable.map == 1 AND
2: "Dungeons", // map.areaType == 1
3: "Raids", // map.areaType == 2
6: "Battlegrounds", // map.areaType == 3
8: "Outland", // areaTable.map == 530 AND
9: "Arenas" // map.areaType == 4
10: "Northrend", // areaTable.map == 571 AND
};
var g_zone_instancetypes = {
1: "Transit", // [manual]
2: "Dungeon",
3: "Raid", // Classic
4: "Battleground", // map.isBattleground
5: "Dungeon", // Heroic
6: "Arena", // map.areaType == 4
7: "Raid", // 10-25
8: "Raid" // 10-25 Heroic
};
var g_zone_territories = {
0: "Alliance", // areaTable.factionGroupMask == 2
1: "Horde", // areaTable.factionGroupMask == 4
2: "Contested", // areaTable.factionGroupMask == 6
3: "Sanctuary", // areaTable.flags & AREA_FLAG_SANCTUARY
4: "PvP", // map.areaType IN [3, 4]
5: "World PvP" // areaTable.flags & AREA_FLAG_WINTERGRASP
};
visibleCols: ['heroiclevel', 'players']
"id":5004, // areaTable.Id
"category":2, // s.o
"expansion":3, // lfgDungeons.expansion || map.expansion
"territory":2, // s.o.
"instance":5, // s.o.
"nplayers":5, // map.maxPlayers
"reqlevel":77, // access_requirement.level_min
"heroicLevel":85, // access_requirement.level_min
"lfgReqLevel":80, // lfgDungeons.targetLevel
"maxlevel":82, // lfgDungeons.levelMin
"minlevel":80, // lfgDungeons.levelMax
"name":"Abyssal Maw: Throne of the Tides", // areaTable.name_X
*/
foreach ($this->iterate() as $__)
{
$data[$this->id] = array(

View File

@@ -918,7 +918,8 @@ class Util
'/\$g\s*([^:;]+)\s*:\s*([^:;]+)\s*(:?[^:;]*);/ui',// directed gender-reference $g:<male>:<female>:<refVariable>
'/\$t([^;]+);/ui', // nonsense, that the client apparently ignores
'/\|\d\-?\d?\((\$\w)\)/ui', // and another modifier for something russian |3-6($r)
'/<([^\"=\/>]+\s[^\"=\/>]+)>/ui' // emotes (workaround: at least one whitespace and never " or = between brackets)
'/<([^\"=\/>]+\s[^\"=\/>]+)>/ui', // emotes (workaround: at least one whitespace and never " or = between brackets)
'/\$(\d+)w/ui' // worldState(?)-ref found on some pageTexts $1234w
);
$to = array(
@@ -927,7 +928,8 @@ class Util
'&lt;\1/\2&gt;',
'',
'\1',
'&lt;\1&gt;'
'&lt;\1&gt;',
'<span class="q0">WorldState #\1</span>'
);
$text = preg_replace($from, $to, $text);
@@ -1525,38 +1527,29 @@ class Util
*/
}
// setup only
private static $alphaMapCache = [];
public static function alphaMapCheck($areaId, array &$coords)
public static function alphaMapCheck($areaId, array &$set)
{
$file = 'cache/alphaMaps/'.$areaId.'.png';
if (!file_exists($file))
{
self::addNote(U_GROUP_STAFF, 'Util::alphaMapCheck no suitable alphaMap found for area '.$areaId.'. Positional check omitted!');
if (!file_exists($file)) // file does not exist (probably instanced area)
return false;
// invalid and corner cases (literally)
if (!is_array($set) || empty($set['posX']) || empty($set['posY']) || $set['posX'] == 100 || $set['posY'] == 100)
{
$set = null;
return true;
}
if (empty(self::$alphaMapCache[$areaId]))
self::$alphaMapCache[$areaId] = imagecreatefrompng($file);
foreach ($coords as $idx => $set)
{
// invalid and corner cases (literally)
if (!is_array($set) || empty($set['xPos']) || empty($set['yPos']) || $set['xPos'] == 100 || $set['yPos'] == 100)
{
unset($coords[$idx]);
continue;
}
// alphaMaps are 1000 x 1000, adapt points [0 => black => valid point]
if (imagecolorat(self::$alphaMapCache[$areaId], $set['posX'] * 10, $set['posY'] * 10))
$set = null;
// alphaMaps are 1000 x 1000, adapt points [0 => black => valid point]
if (imagecolorat(self::$alphaMapCache[$areaId], $set['xPos'] * 10, $set['yPos'] * 10))
unset($coords[$idx]);
}
if ($coords)
$coords = array_values($coords); // kill indizes
return $coords ? true : false;
return true;
}
public static function getServerConditions($srcType, $srcGroup = null, $srcEntry = null)

View File

@@ -48,6 +48,8 @@ $lang = array(
'n_a' => "n. v.",
'siteRep' => "Ruf",
'aboutUs' => "Über Aowow",
'and' => " und ",
'or' => " oder ",
// filter
'extSearch' => "Erweiterte Suche",
@@ -192,6 +194,7 @@ $lang = array(
'zone' => "Zone",
'zones' => "Gebiete",
'pvp' => "PvP",
'honorPoints' => "Ehrenpunkte",
'arenaPoints' => "Arenapunkte",
'heroClass' => "Heldenklasse",
@@ -202,7 +205,9 @@ $lang = array(
'specs' => "Spezialisierungen",
'_roles' => ["Heiler", "Nahkampf-DPS", "Distanz-DPS", "Tank"],
'modes' => ["Normal / Normal 10", "Heroisch / Normal 25", "Heroisch 10", "Heroisch 25"],
'phases' => "Phasen",
'mode' => "Modus",
'modes' => [-1 => "Beliebig", "Normal / Normal 10", "Heroisch / Normal 25", "Heroisch 10", "Heroisch 25"],
'expansions' => ["Classic", "The Burning Crusade", "Wrath of the Lich King"],
'stats' => ["Stärke", "Beweglichkeit", "Ausdauer", "Intelligenz", "Willenskraft"],
'sources' => array(
@@ -352,7 +357,7 @@ $lang = array(
'capturePoint' => "Eroberungspunkt",
'foundIn' => "Dieses Objekt befindet sich in"
),
'npc' => array(
'npc' => array(
'classification'=> "Einstufung",
'petFamily' => "Tierart",
'react' => "Reaktion",
@@ -370,6 +375,9 @@ $lang = array(
'armor' => "Rüstung",
'foundIn' => "Dieser NPC befindet sich in",
'tameable' => "Zähmbar (%s)",
'waypoint' => "Wegpunkt",
'wait' => "Wartezeit",
'respawnIn' => "Wiedereinstieg in",
'rank' => [0 => "Normal", 1 => "Elite", 4 => "Rar", 2 => "Rar Elite", 3 => "Boss"],
'textRanges' => [null, "an das Gebiet gesendet", "an die Zone gesendet", "an die Map gesendet", "an die Welt gesendet"],
'textTypes' => [null, "schreit", "sagt", "flüstert"],
@@ -420,11 +428,17 @@ $lang = array(
'Miscellaneous' => "Diverse",
'Azeroth' => "Azeroth",
'CosmicMap' => "Kosmische Karte",
'selectorLink' => " und ",
),
'zone' => array(
// 'zone' => "Zone",
// 'zonePartOf' => "Diese Zone ist Teil der Zone",
'city' => "Stadt",
'territory' => "Territorium",
'instanceType' => "Instanzart",
'hcAvailable' => "Heroischer Modus verfügbar&nbsp;(%d)",
'numPlayers' => "Anzahl an Spielern",
'noMap' => "Für dieses Gebiet steht keine Karte zur Verfügung.",
'instanceTypes' => ["Zone", "Durchgang", "Dungeon", "Schlachtzug", "Battleground", "Dungeon", "Arena", "Schlachtzug", "Schlachtzug"],
'territories' => ["Allianz", "Horde", "Umkämpft", "Sicheres Gebiet", "PvP", "Welt-PvP"],
'cat' => array(
"Östliche Königreiche", "Kalimdor", "Dungeons", "Schlachtzüge", "Unbenutzt", null,
"Schlachtfelder", null, "Scherbenwelt", "Arenen", "Nordend"

View File

@@ -43,6 +43,8 @@ $lang = array(
'n_a' => "n/a",
'siteRep' => "Reputation",
'aboutUs' => "About us & contact",
'and' => " and ",
'or' => " or ",
// filter
'extSearch' => "Extended search",
@@ -187,6 +189,7 @@ $lang = array(
'zone' => "zone",
'zones' => "Zones",
'pvp' => "PvP",
'honorPoints' => "Honor Points",
'arenaPoints' => "Arena Points",
'heroClass' => "Hero class",
@@ -197,7 +200,9 @@ $lang = array(
'specs' => "Specs",
'_roles' => ["Healer", "Melee DPS", "Ranged DPS", "Tank"],
'modes' => ["Normal / Normal 10", "Heroic / Normal 25", "Heroic 10", "Heroic 25"],
'phases' => "Phases",
'mode' => "Mode",
'modes' => [-1 => "Any", "Normal / Normal 10", "Heroic / Normal 25", "Heroic 10", "Heroic 25"],
'expansions' => ["Classic", "The Burning Crusade", "Wrath of the Lich King"],
'stats' => ["Strength", "Agility", "Stamina", "Intellect", "Spirit"],
'sources' => array(
@@ -365,6 +370,9 @@ $lang = array(
'armor' => "Armor",
'foundIn' => "This NPC can be found in",
'tameable' => "Tameable (%s)",
'waypoint' => "Waypoint",
'wait' => "Wait",
'respawnIn' => "Respawn in",
'rank' => [0 => "Normal", 1 => "Elite", 4 => "Rare", 2 => "Rare Elite", 3 => "Boss"],
'textRanges' => [null, "sent to area", "sent to zone", "sent to map", "sent to world"],
'textTypes' => [null, "yells", "says", "whispers"],
@@ -415,11 +423,17 @@ $lang = array(
'Miscellaneous' => "Miscellaneous",
'Azeroth' => "Azeroth",
'CosmicMap' => "Cosmic Map",
'selectorLink' => " and ",
),
'zone' => array(
// 'zone' => "Zone",
// 'zonePartOf' => "This zone is part of",
'city' => "City",
'territory' => "Territory",
'instanceType' => "Instance type",
'hcAvailable' => "Heroic mode available &nbsp;(%d)",
'numPlayers' => "Number of players",
'noMap' => "There is no map available for this zone.",
'instanceTypes' => ["Zone", "Transit", "Dungeon", "Raid", "Battleground", "Dungeon", "Arena", "Raid", "Raid"],
'territories' => ["Alliance", "Horde", "Contested", "Sanctuary", "PvP", "World PvP"],
'cat' => array(
"Eastern Kingdoms", "Kalimdor", "Dungeons", "Raids", "Unused", null,
"Battlegrounds", null, "Outland", "Arenas", "Northrend"

View File

@@ -48,6 +48,8 @@ $lang = array(
'n_a' => "n/d",
'siteRep' => "Reputación",
'aboutUs' => "Sobre Aowow",
'and' => " y ",
'or' => " o ",
// filter
'extSearch' => "Extender búsqueda",
@@ -192,6 +194,7 @@ $lang = array(
'zone' => "zona",
'zones' => "Zonas",
'pvp' => "JcJ",
'honorPoints' => "Puntos de Honor",
'arenaPoints' => "Puntos de arena",
'heroClass' => "Clase héroe",
@@ -202,7 +205,9 @@ $lang = array(
'specs' => "Especializaciones",
'_roles' => ["Sanador", "DPS cuerpo", "DPS a distancia", "Tanque"],
'modes' => ["Normal / Normal 10", "Heroico / Normal 25", "Heróico 10", "Heróico 25"],
'phases' => "Fases",
'mode' => "Modo",
'modes' => [-1 => "Cualquiera", "Normal / Normal 10", "Heroico / Normal 25", "Heróico 10", "Heróico 25"],
'expansions' => ["World of Warcraft", "The Burning Crusade", "Wrath of the Lich King"],
'stats' => ["Fuerza", "Agilidad", "Aguante", "Intelecto", "Espíritu"],
'sources' => array(
@@ -352,7 +357,7 @@ $lang = array(
'triggeredBy' => "Accionado por",
'capturePoint' => "Punto de captura"
),
'npc' => array(
'npc' => array(
'classification'=> "Clasificación",
'petFamily' => "Familia de mascota",
'react' => "Reacción",
@@ -369,6 +374,9 @@ $lang = array(
'ranged' => "Ataque a distancia",
'armor' => "Armadura",
'tameable' => "Domesticable (%s)",
'waypoint' => "punto de recorrido",
'wait' => "Tiempo de espera",
'respawnIn' => "Reingreso en",
'rank' => [0 => "Normal", 1 => "Élite", 4 => "Raro", 2 => "Élite raro", 3 => "Jefe"],
'textRanges' => [null, "[sent to area]", "[sent to zone]", "[sent to map]", "[sent to world]"],
'textTypes' => [null, "grita", "dice", "susurra"],
@@ -421,8 +429,15 @@ $lang = array(
'CosmicMap' => "Mapa cósmico",
),
'zone' => array(
// 'zone' => "Zone",
// 'zonePartOf' => "Cette zone fait partie de la zone",
'city' => "Ciudad",
'territory' => "Territorio",
'instanceType' => "Tipo de instancia",
'hcAvailable' => "Modo heroico disponible&nbsp;(%di)",
'numPlayers' => "Número de jugadores",
'noMap' => "No hay mapa disponible para esta zona.",
'instanceTypes' => ["Zona", "Tránsito", "Mazmorra", "Banda", "Campo de batalla", "Mazmorra", "Arena", "Banda", "Banda"],
'territories' => ["Alianza", "Horda", "En disputa", "Santuario", "JcJ", "JcJ abierto"],
'cat' => array(
"Reinos del Este", "Kalimdor", "Mazmorras", "Bandas", "No las uso", null,
"Campos de batalla", null, "Terrallende", "Arenas", "Rasganorte"

View File

@@ -48,6 +48,8 @@ $lang = array(
'n_a' => "n/d",
'siteRep' => "Réputation",
'aboutUs' => "À propos de Aowow",
'and' => " et ",
'or' => " ou ",
// filter
'extSearch' => "Recherche avancée",
@@ -192,6 +194,7 @@ $lang = array(
'zone' => "zone",
'zones' => "Zones",
'pvp' => "JcJ",
'honorPoints' => "Points d'honneur",
'arenaPoints' => "Points d'arène",
'heroClass' => "Classe de héros",
@@ -202,7 +205,9 @@ $lang = array(
'specs' => "Specialisations",
'_roles' => ["Soigneur", "DPS mêlée", "DPS à distance", "Tank"],
'modes' => ["Standard / Normal 10", "Héroïque / Normal 25", "10 héroïque", "25 héroïque"],
'phases' => "Phases",
'mode' => "Mode",
'modes' => [-1 => "Tout", "Standard / Normal 10", "Héroïque / Normal 25", "10 héroïque", "25 héroïque"],
'expansions' => ["Classique", "The Burning Crusade", "Wrath of the Lich King"],
'stats' => ["Force", "Agilité", "Endurance", "Intelligence", "Esprit"],
'sources' => array(
@@ -351,7 +356,7 @@ $lang = array(
'triggeredBy' => "Déclenché par",
'capturePoint' => "Point de capture"
),
'npc' => array(
'npc' => array(
'classification'=> "Classification",
'petFamily' => "Familier",
'react' => "Réaction",
@@ -368,6 +373,9 @@ $lang = array(
'ranged' => "à distance",
'armor' => "Armure",
'tameable' => "Domptable (%s)",
'waypoint' => "Point de route",
'wait' => "Période d'attente",
'respawnIn' => "Rentrée en",
'rank' => [0 => "Standard", 1 => "Élite", 4 => "Rare", 2 => "Élite rare", 3 =>"Boss"],
'textRanges' => [null, "[sent to area]", "[sent to zone]", "[sent to map]", "[sent to world]"],
'textTypes' => [null, "crie", "dit", "chuchote"],
@@ -420,8 +428,15 @@ $lang = array(
'CosmicMap' => "Carte cosmique",
),
'zone' => array(
// 'zone' => "Zone",
// 'zonePartOf' => "Cette zone fait partie de la zone",
'city' => "Город",
'territory' => "Territoire",
'instanceType' => "Type d'instance",
'hcAvailable' => "Mode héroïque disponible&nbsp;(%d)",
'numPlayers' => "Nombre de joueurs",
'noMap' => "Il n'y a aucune carte disponible pour cette zone.",
'instanceTypes' => ["Zone", "Transit", "Donjon", "Raid", "Champ de bataille", "Donjon", "Arène", "Raid", "Raid"],
'territories' => ["Alliance", "Horde", "Contesté", "Sanctuaire", "JcJ", "JcJ Global"],
'cat' => array(
"Royaumes de l'est", "Kalimdor", "Donjons", "Raids", "Inutilisées", null,
"Champs de bataille", null, "Outreterre", "Arènes", "Norfendre"

View File

@@ -48,6 +48,8 @@ $lang = array(
'n_a' => "нет",
'siteRep' => "Репутация",
'aboutUs' => "О Aowow",
'and' => " и ",
'or' => " или ",
// filter
'extSearch' => "Расширенный поиск",
@@ -192,6 +194,7 @@ $lang = array(
'zone' => "игровая зона",
'zones' => "Местности",
'pvp' => "PvP",
'honorPoints' => "Очки Чести",
'arenaPoints' => "Очки арены",
'heroClass' => "Героический класс",
@@ -202,7 +205,9 @@ $lang = array(
'specs' => "Ветки талантов",
'_roles' => ["Лекарь", "Боец ближнего боя", "Боец дальнего боя", "Танк"],
'modes' => ['Обычный / 10-норм.", "Героический / 25-норм.", "10-героич", "25-героич'],
'phases' => "Фазы",
'mode' => "Режим",
'modes' => [-1 => "Все", "Обычный / 10-норм.", "Героический / 25-норм.", "10-героич", "25-героич"],
'expansions' => array("World of Warcraft", "The Burning Crusade", "Wrath of the Lich King"),
'stats' => array("к силе", "к ловкости", "к выносливости", "к интеллекту", "к духу"),
'sources' => array(
@@ -351,7 +356,7 @@ $lang = array(
'triggeredBy' => "Срабатывает от",
'capturePoint' => "Точка захвата"
),
'npc' => array(
'npc' => array(
'classification'=> "Классификация",
'petFamily' => "Семейство питомца",
'react' => "Реакция",
@@ -368,6 +373,9 @@ $lang = array(
'ranged' => "Дальнего боя",
'armor' => "Броня",
'tameable' => "Можно приручить (%s)",
'waypoint' => "Путевой точки",
'wait' => "Период ожидания",
'respawnIn' => "Reentry in", /// ..lol?
'rank' => [0 => "Обычный", 1 => "Элитный", 4 => "Редкий", 2 => "Редкий элитный", 3 =>"Босс"],
'textRanges' => [null, "[sent to area]", "[sent to zone]", "[sent to map]", "[sent to world]"],
'textTypes' => [null, "кричит", "говорит", "шепчет"],
@@ -420,8 +428,15 @@ $lang = array(
'CosmicMap' => "Звёздная карта",
),
'zone' => array(
// 'zone' => "Игровая зона",
// 'zonePartOf' => "Эта игровая локация является частью локации",
'city' => "Город",
'territory' => "Территория",
'instanceType' => "Тип подземелья",
'hcAvailable' => "Доступен героический режим&nbsp;(%d)",
'numPlayers' => "Количество игроков",
'noMap' => "Для данной местности нет доступной карты.",
'instanceTypes' => ["Игровая зона", "Транзит", "Подземелье", "Рейд", "Поле боя", "Подземелье", "Арена", "Рейд", "Рейд"],
'territories' => ["Альянс", "Орда", "Оспариваемая", "Святилище", "PvP", "Мировое PvP"],
'cat' => array(
"Восточные королевства", "Калимдор", "Подземелья", "Рейды", "Неактивно", null,
"Поля боя", null, "Запределье", "Арены", "Нордскол"

View File

@@ -214,7 +214,7 @@ class CurrencyPage extends GenericPage
'name' => '$LANG.tab_currencyfor',
'id' => 'currency-for',
'extraCols' => "$[Listview.funcBox.createSimpleCol('stack', 'stack', '10%', 'stack')]",
'note' => $n ? '$$WH.sprintf(LANG.lvnote_filterresults, \''.$n.'\')' : null
'note' => $n ? sprintf(Util::$filterResultString, $n) : null
]
);

View File

@@ -287,7 +287,7 @@ class GenericPage
$this->announcements = [];
// display occured notices
if ($_ = Util::getNotes(false))
if ($_ = Util::getNotes())
{
$this->announcements[] = array(
'id' => 0,

View File

@@ -18,10 +18,10 @@ class NpcPage extends GenericPage
protected $mode = CACHE_TYPE_PAGE;
protected $js = array(
'swfobject.js',
// 'Mapper.js'
'Mapper.js'
);
protected $css = array(
// ['path' => 'Mapper.css']
['path' => 'Mapper.css']
);
public function __construct($pageCall, $id)
@@ -57,6 +57,8 @@ class NpcPage extends GenericPage
protected function generateContent()
{
$this->addJS('?data=zones&locale='.User::$localeId.'&t='.$_SESSION['dataKey']);
$_typeFlags = $this->subject->getField('typeFlags');
$_altIds = [];
$_altNPCs = null;
@@ -79,14 +81,24 @@ class NpcPage extends GenericPage
$_altNPCs = new CreatureList(array(['id', array_keys($_altIds)]));
}
// hmm, this won't do if the creature is spawned by event/script
$mapType = 2; // should be 0, tmp-override until Zones
// $maps = DB::Aowow()->selectCol('SELECT DISTINCT map from creature WHERE id = ?d', $this->typeId);
// if (count($maps) == 1) // should only exist in one instance
// {
// $map = new ZoneList(array(1, ['mapId', $maps[0]], ['parentArea', 0]));
// $mapType = $map->getField('areaType');
// }
// try to determine, if it's spawned in a dungeon or raid (shaky at best, if spawned by script)
$mapType = 0;
if ($maps = DB::Aowow()->selectCol('SELECT DISTINCT areaId from ?_spawns WHERE type = ?d AND typeId = ?d', TYPE_NPC, $this->typeId))
{
if (count($maps) == 1) // should only exist in one instance
{
$map = new ZoneList(array(['id', $maps], 1));
if (!$map->error)
$mapType = $map->getField('areaType');
}
}
else if ($_altIds) // not spawned, but has difficultyDummies
{
if (count($_altIds) > 1) // 3 or more version -> definitly raid (10/25 + hc)
$mapType = 2;
else // 2 versions; may be Heroic (use this), but may also be 10/25-raid
$mapType = 1;
}
/***********/
/* Infobox */
@@ -95,10 +107,14 @@ class NpcPage extends GenericPage
$infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags'));
// Event
if ($_ = DB::Aowow()->selectCell('SELECT holidayId FROM ?_events e, game_event_creature gec, creature c WHERE e.id = ABS(gec.eventEntry) AND c.guid = gec.guid AND c.id = ?d', $this->typeId))
if ($_ = DB::Aowow()->selectCol('SELECT DISTINCT IF(holidayId, holidayId, -e.id) FROM ?_events e, game_event_creature gec, creature c WHERE e.id = ABS(gec.eventEntry) AND c.guid = gec.guid AND c.id = ?d', $this->typeId))
{
$this->extendGlobalIds(TYPE_WORLDEVENT, $_);
$infobox[] = Util::ucFirst(Lang::$game['eventShort']).Lang::$main['colon'].'[event='.$_.']';
$ev = [];
foreach ($_ as $idx => $id)
$ev[] = ($ev && !fmod(count($ev), 2) ? '[br]' : '') . '[event='.$id.']';
$infobox[] = Util::ucFirst(Lang::$game['eventShort']).Lang::$main['colon'].implode(', ', $ev);
}
// Level
@@ -235,13 +251,24 @@ class NpcPage extends GenericPage
/* Main Content */
/****************/
// get spawns and such
// get spawns and path
$map = null;
if ($spawns = $this->subject->getSpawns(SPAWNINFO_FULL))
{
$map = ['data' => ['parent' => 'mapper-generic'], 'mapperData' => &$spawns];
// consider phaseMasks
foreach ($spawns as $areaId => &$areaData)
{
$map['extra'][$areaId] = ZoneList::getName($areaId);
foreach ($areaData as &$floor)
$floor['count'] = count($floor['coords']);
}
}
// consider pooled spawns
// $this->mapper = true,
$this->map = $map;
$this->infobox = '[ul][li]'.implode('[/li][li]', $infobox).'[/li][/ul]';
$this->position = $position;
$this->quotes = $this->getQuotes();
@@ -539,7 +566,7 @@ class NpcPage extends GenericPage
$sf[4][] = 'Listview.extraCols.condition';
$reqQuest[$lv['id']] = 0;
$lv['condition'][] = ['type' => TYPE_QUEST, 'typeId' => &$reqQuest[$lv['id']], 'status' => 1];
$lv['condition'][0][$this->typeId][] = [[CND_QUESTTAKEN, &$reqQuest[$lv['id']]]];
}
$this->lvTabs[] = array(
@@ -834,8 +861,11 @@ class NpcPage extends GenericPage
$group = [];
foreach ($text as $t)
{
// fixup .. either set %s for emotes or dont >.<
$msg = Util::localizedString($t, 'text');
if (!$msg)
continue;
// fixup .. either set %s for emotes or dont >.<
if (in_array($t['type'], [2, 16]) && strpos($msg, '%s') === false)
$msg = '%s '.$msg;
@@ -863,7 +893,9 @@ class NpcPage extends GenericPage
$nQuotes++;
$group[] = $line;
}
$quotes[] = $group;
if ($group)
$quotes[] = $group;
}
return [$quotes, $nQuotes];

View File

@@ -18,10 +18,10 @@ class ObjectPage extends GenericPage
protected $mode = CACHE_TYPE_PAGE;
protected $js = array(
'swfobject.js',
// 'Mapper.js'
'Mapper.js'
);
protected $css = array(
// ['path' => 'Mapper.css']
['path' => 'Mapper.css']
);
/* NOTE
@@ -60,6 +60,8 @@ class ObjectPage extends GenericPage
protected function generateContent()
{
$this->addJS('?data=zones&locale='.User::$localeId.'&t='.$_SESSION['dataKey']);
/***********/
/* Infobox */
/***********/
@@ -219,30 +221,25 @@ class ObjectPage extends GenericPage
$this->addJS('Book.js');
}
// positions
$positions = [];
/*
$positions = position($object['entry'], 'gameobject');
// Исправить type, чтобы подсвечивались event-овые объекты
if ($object['position'])
foreach ($object['position'] as $z => $zone)
foreach ($zone['points'] as $p => $pos)
if ($pos['type'] == 0 && ($events = event_find(array('object_guid' => $pos['guid']))))
{
$names = arraySelectKey(event_name($events), 'name');
$object['position'][$z]['points'][$p]['type'] = 4;
$object['position'][$z]['points'][$p]['events'] = implode(", ", $names);
}
*/
// get spawns and path
$map = null;
if ($spawns = $this->subject->getSpawns(SPAWNINFO_FULL))
{
$map = ['data' => ['parent' => 'mapper-generic'], 'mapperData' => &$spawns];
// consider phaseMasks
foreach ($spawns as $areaId => &$areaData)
{
$map['extra'][$areaId] = ZoneList::getName($areaId);
foreach ($areaData as &$floor)
$floor['count'] = count($floor['coords']);
}
}
// consider pooled spawns
$this->infobox = $infobox ? '[ul][li]'.implode('[/li][li]', $infobox).'[/li][/ul]' : null;
$this->pageText = $pageText;
$this->positions = $positions;
$this->map = $map;
$this->redButtons = array(
BUTTON_WOWHEAD => true,
BUTTON_LINKS => true,

466
pages/zone.php Normal file

File diff suppressed because one or more lines are too long

View File

@@ -35,9 +35,10 @@ class ZonesPage extends GenericPage
protected function generateContent()
{
$conditions = [];
$conditions = [CFG_SQL_LIMIT_NONE];
$visibleCols = [];
$hiddenCols = [];
$params = [];
$mapFile = 0;
$spawnMap = -1;
@@ -47,6 +48,7 @@ class ZonesPage extends GenericPage
if ($this->category)
{
$conditions[] = ['z.category', $this->category[0]];
$hiddenCols[] = 'category';
if (isset($this->category[1]) && in_array($this->category[0], [2, 3]))
$conditions[] = ['z.expansion', $this->category[1]];
@@ -59,17 +61,38 @@ class ZonesPage extends GenericPage
case 1: $mapFile = -6; $spawnMap = 1; break;
case 8: $mapFile = -2; $spawnMap = 530; break;
case 10: $mapFile = -5; $spawnMap = 571; break;
}
}
$hiddenCols[] = 'instancetype';
}
switch ($this->category[0])
{
case 6:
case 2:
case 2:
case 3:
array_push($visibleCols, 'level', 'players');
case 9:
$hiddenCols[] = 'territory';
break;
}
}
$zones = new ZoneList($conditions);
$this->map = null;
if ($visibleCols)
$params['visibleCols'] = "$['".implode("', '", $visibleCols)."']";
if ($hiddenCols)
$params['hiddenCols'] = "$['".implode("', '", $hiddenCols)."']";
$this->map = null;
$this->lvTabs[] = array(
'file' => 'zone',
'data' => $zones->getListviewData(),
'params' => []
'params' => $params
);
// create flight map
@@ -139,7 +162,8 @@ class ZonesPage extends GenericPage
'zoomable' => false,
'parent' => 'mapper-generic'
),
'som' => $somData
'som' => $somData,
'mapperData' => [$mapFile => new stdClass()]
);
}
}

Binary file not shown.

Binary file not shown.

View File

@@ -1,51 +0,0 @@
-- --------------------------------------------------------
-- Host: 127.0.0.1
-- Server Version: 5.6.14 - MySQL Community Server (GPL)
-- Server Betriebssystem: Win32
-- HeidiSQL Version: 8.3.0.4694
-- --------------------------------------------------------
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
-- Exportiere Datenbank Struktur für world
CREATE DATABASE IF NOT EXISTS `world` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `world`;
-- Exportiere Struktur von Tabelle world.aowow_config
CREATE TABLE IF NOT EXISTS `aowow_config` (
`key` varchar(25) NOT NULL,
`intValue` mediumint(9) DEFAULT NULL,
`strValue` varchar(255) DEFAULT NULL,
`comment` varchar(255) NOT NULL,
PRIMARY KEY (`key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- Exportiere Daten aus Tabelle world.aowow_config: 16 rows
DELETE FROM `aowow_config`;
/*!40000 ALTER TABLE `aowow_config` DISABLE KEYS */;
INSERT INTO `aowow_config` (`key`, `intValue`, `strValue`, `comment`) VALUES
('sql_limit_search', 500, NULL, 'default: 500 - Limit of some SQL queries'),
('sql_limit_default', 300, NULL, 'default: 300 - Limit of some SQL queries'),
('sql_limit_quicksearch', 15, NULL, 'default: 10 - Limit of some SQL queries'),
('sql_limit_none', 0, NULL, 'default: 0 - Limit of some SQL queries (yes, i\'m lazy)'),
('ttl_rss', 60, NULL, 'default: 60 - time to live for RSS'),
('cache_decay', 604800, NULL, 'default: 60 * 60 * 7 - Time to keep cache in seconds'),
('session_timeout_delay', 3600, NULL, 'default: 60 * 60 - non-permanent session times out in time() + X'),
('failed_auth_exclusion', 900, NULL, 'default: 15 * 60 - how long an account is closed after exceeding failed_auth_count'),
('failed_auth_count', 5, NULL, 'default: 5 - how often invalid passwords are tolerated'),
('name', NULL, 'Aowow Database Viewer (ADV)', 'website title'),
('shortname', NULL, 'Aowow', 'feed title'),
('boardurl', NULL, 'http://www.wowhead.com/forums?board=', 'a javascript thing..'),
('contact_email', NULL, 'feedback@aowow.org', 'ah well...'),
('battlegroup', NULL, 'Pure Pwnage', 'pretend, we belong to a battlegroup to satisfy profiler-related Jscripts; region can be determined from realmlist.timezone'),
('allow_register', 1, NULL, 'default: 1 - Allow account creating'),
('debug', 1, NULL, 'default: 0 - Disable cache, show smarty console panel, enable sql-errors'),
('maintenance', 0, NULL, 'default: 0 - brb gnomes say hi');
/*!40000 ALTER TABLE `aowow_config` ENABLE KEYS */;
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +0,0 @@
ALTER TABLE `aowow_achievement` CHANGE COLUMN `rewardIds` `itemExtra` MEDIUMINT(8) UNSIGNED NOT NULL AFTER `refAchievement`;
UPDATE `aowow_achievement` SET `itemExtra` = 0;
UPDATE `aowow_achievement` SET `itemExtra` = 44738 WHERE `id` = 1956;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,9 +0,0 @@
UPDATE aowow_achievement SET iconString = LOWER(iconString);
UPDATE aowow_creature SET iconString = LOWER(iconString);
UPDATE aowow_currencies SET iconString = LOWER(iconString);
UPDATE aowow_holidays SET iconString = LOWER(iconString);
UPDATE aowow_items SET iconString = LOWER(iconString);
UPDATE aowow_pet SET iconString = LOWER(iconString);
UPDATE aowow_shapeshiftforms SET iconString = LOWER(iconString);
UPDATE aowow_skillline SET iconString = LOWER(iconString);
UPDATE aowow_spell SET iconString = LOWER(iconString);

View File

@@ -1,2 +0,0 @@
INSERT IGNORE INTO aowow_config (`key`, `intValue`, `comment`) VALUES ('force_ssl', 0, 'default: 0 - enforce SSL, if the server is behind a load balancer');

View File

@@ -1,2 +0,0 @@
INSERT IGNORE INTO aowow_config (`key`, `intValue`, `comment`) VALUES ('cache_mode', 1, 'default: 1 - set cache method (0: none; 1:filecache; 2:memcached; 3:both)');

File diff suppressed because one or more lines are too long

View File

@@ -1,18 +0,0 @@
UPDATE aowow_creature SET cuFlags = cuFlags | 0x40000000 WHERE
name_loc0 like '%(%' OR
name_loc0 like '%[%' OR
name_loc0 like '%<%' OR
name_loc0 like '%placeholder%' OR
name_loc0 like '%DND%' OR
name_loc0 like '%UNUSED%';
UPDATE aowow_currencies SET cuFlags = cuFlags | 0x40000000 WHERE
id IN (1, 2, 4, 22, 141);
UPDATE aowow_skillline SET cuFlags = cuFlags | 0x40000000 WHERE
id IN (769, 142, 148, 149, 150, 152, 155, 533, 553, 554, 713, 183);
UPDATE aowow_items SET cuFlags = cuFlags | 0x40000000 WHERE
name_loc0 like '%[%' OR
name_loc0 like '%(PH)%' OR
name_loc0 like '%(DEPRECATED)%';

View File

@@ -1,2 +0,0 @@
-- type 0 causes trouble with g_pageInfo
UPDATE aowow_articles SET `type` = -1 WHERE `type` = 0;

View File

@@ -1,3 +0,0 @@
INSERT INTO aowow_config (`key`, `intValue`, `comment`) VALUES
('account_create_save_decay', 604800, 'default: 604800 - [1 week] time in wich an unconfirmed account cannot be overwritten by new registrations'),
('account_recovery_decay', 300, 'default: 300 - [5 min] time to recover your account and new recovery requets are blocked');

View File

@@ -1,11 +0,0 @@
ALTER TABLE `aowow_account`
ALTER `curIP` DROP DEFAULT,
ALTER `prevIP` DROP DEFAULT;
ALTER TABLE `aowow_account`
CHANGE COLUMN `curIP` `curIP` VARCHAR(45) NOT NULL AFTER `consecutiveVisits`,
CHANGE COLUMN `prevIP` `prevIP` VARCHAR(45) NOT NULL AFTER `curIP`;
ALTER TABLE `aowow_account_bannedips`
ALTER `ip` DROP DEFAULT;
ALTER TABLE `aowow_account_bannedips`
CHANGE COLUMN `ip` `ip` VARCHAR(45) NOT NULL FIRST;

View File

@@ -1,39 +1,71 @@
<?php
if (!empty($this->map['data'])):
if ($this->map['data']['zone'] < 0):
if (isset($this->map) && empty($this->map)):
echo Lang::$zone['noMap'];
elseif (!empty($this->map['data'])):
if ($this->type != TYPE_ZONE):
echo ' <div>'.($this->type == TYPE_OBJECT ? Lang::$gameObject['foundIn'] : Lang::$npc['foundIn']).' <span id="locations">';
$n = count($this->map['mapperData']);
$i = 0;
foreach ($this->map['mapperData'] as $areaId => $areaData):
if ($n > 1 && $i++ > 0):
echo $i < $n ? ', ' : Lang::$main['and'];
endif;
echo '<a href="javascript:;" onclick="myMapper.update({zone: '.$areaId.'}); g_setSelectedLink(this, \'mapper\'); return false" onmousedown="return false">'.$this->map['extra'][$areaId].'</a>&nbsp;('.reset($areaData)['count'].')';
endforeach;
echo ".</span></div>\n";
endif;
if (!empty($this->map['data']['zone']) && $this->map['data']['zone'] < 0):
?>
<div id="mapper" style="width: 778px; margin: 0 auto">
<?php if (isset($this->map['som'])): ?>
<?php
if (isset($this->map['som'])):
?>
<div id="som-generic"></div>
<?php endif; ?>
<?php
endif;
?>
<div id="mapper-generic"></div>
<div class="pad clear"></div>
</div>
<?php else: ?>
<?php
else:
?>
<div class="pad"></div>
<?php if (isset($this->map['som'])): ?>
<?php
if (isset($this->map['som'])):
?>
<div id="som-generic"></div>
<?php
endif;
if (isset($this->map['mapperData'])):
endif;
?>
<div><?php echo Lang::$map['foundIn']; ?> <span id="locations"><?php echo $this->map['mapSelector']; ?>.</span></div>
<?php endif; ?>
<div id="mapper-generic"></div>
<div style="clear: left"></div>
<?php endif; ?>
<?php
endif;
?>
<script type="text/javascript">//<![CDATA[
<?php if ($this->map['data']['zone'] < 0): ?>
var g_pageInfo = {id:<?php echo $this->map['data']['zone']; ?>};
<?php elseif (!empty($this->map['mapperData'])): ?>
var g_mapperData = <?php echo $this->map['mapperData']; ?>;
<?php else: ?>
var g_mapperData = {<?php echo $this->map['data']['zone']; ?>: {}};
<?php endif; ?>
var myMapper = new Mapper(<?php echo json_encode($this->map['data'], JSON_NUMERIC_CHECK); /* dont forget to set "'parent' => 'mapper-generic'" */ ?>);
<?php if (!empty($this->map['som'])): ?>
new ShowOnMap(<?php echo json_encode($this->map['som'], JSON_NUMERIC_CHECK); ?>);
<?php endif; ?>
<?php
if (!empty($this->map['data']['zone'])):
echo " var g_pageInfo = {id: ".$this->map['data']['zone']."};\n";
elseif (!empty($this->map['mapperData'])):
echo " var g_mapperData = ".json_encode($this->map['mapperData'], JSON_NUMERIC_CHECK).";\n";
endif;
// dont forget to set "parent: 'mapper-generic'"
echo " var myMapper = new Mapper(".json_encode($this->map['data'], JSON_NUMERIC_CHECK).");\n";
if (isset($this->map['som'])):
echo " new ShowOnMap(".json_encode($this->map['som'], JSON_NUMERIC_CHECK).");\n";
endif;
if ($this->type != TYPE_ZONE):
echo " \$WH.gE(\$WH.ge('locations'), 'a')[0].onclick();\n";
endif;
?>
//]]></script>
<?php endif; ?>

View File

@@ -25,60 +25,8 @@ if (is_array($this->position)):
?>
<div class="pad"></div>
<?php
elseif (!empty($this->position)):
?>
<div>{#This_NPC_can_be_found_in#}<span id="locations">
{foreach from=$position item=zone name=zone}
<a href="javascript:;" onclick="
{if $zone.atid}
myMapper.update(
{
zone:{$zone.atid}
{if $zone.points}
,
{/if}
{if $zone.points}
coords:[
{foreach from=$zone.points item=point name=point}
[{$point.x},{$point.y},
{
label:'$<br>
<div class=q0>
<small>
{if isset($point.r)}
{#Respawn#}:
{if isset($point.r.h)} {$point.r.h}{#hr#}{/if}
{if isset($point.r.m)} {$point.r.m}{#min#}{/if}
{if isset($point.r.s)} {$point.r.s}{#sec#}{/if}
{else}
{#Waypoint#}
{/if}
{if isset($point.events)}<br>{$point.events|escape:"quotes"}{/if}
</small>
</div>',type:'{$point.type}'
}]
{if !$smarty.foreach.point.last},{/if}
{/foreach}
]
{/if}
});
$WH.ge('mapper-generic').style.display='block';
{else}
$WH.ge('mapper-generic').style.display='none';
{/if}
g_setSelectedLink(this, 'mapper'); return false" onmousedown="return false">
{$zone.name}</a>{if $zone.population > 1}&nbsp;({$zone.population}){/if}{if $smarty.foreach.zone.last}.{else}, {/if}
{/foreach}
</span></div>
<div id="mapper-generic"></div>
<div class="clear"></div>
<script type="text/javascript">
var myMapper = new Mapper({parent: 'mapper-generic', zone: '{$position[0].atid}'});
$WH.gE($WH.ge('locations'), 'a')[0].onclick();
</script>
<?php
elseif (!empty($this->map)):
$this->brick('mapper');
else:
echo ' '.Lang::$npc['unkPosition']."\n";
endif;

View File

@@ -20,55 +20,8 @@
<?php
$this->brick('article');
if ($this->positions):
?>
<div>{#This_Object_can_be_found_in#}
<span id="locations">
{foreach from=$object.position item=zone name=zone}
<a href="javascript:;" onclick="
myMapper.update(
{
{if $zone.atid}
zone:{$zone.atid}
{if $zone.points}
,
{/if}
{else}
show:false
{/if}
{if $zone.points}
coords:[
{foreach from=$zone.points item=point name=point}
[{$point.x},{$point.y},
{
label:'$<br>
<div class=q0>
<small>{#Respawn#}:
{if isset($point.r.h)} {$point.r.h}{#hr#}{/if}
{if isset($point.r.m)} {$point.r.m}{#min#}{/if}
{if isset($point.r.s)} {$point.r.s}{#sec#}{/if}
{if isset($point.events)}<br>{$point.events|escape:"quotes"}{/if}
</small>
</div>',type:'{$point.type}'
}]
{if !$smarty.foreach.point.last},{/if}
{/foreach}
]
{/if}
});
g_setSelectedLink(this, 'mapper'); return false" onmousedown="return false">
{$zone.name}</a>{if $zone.population > 1}&nbsp;({$zone.population}){/if}{if $smarty.foreach.zone.last}.{else}, {/if}
{/foreach}
</span></div>
<div id="mapper-generic"></div>
<div class="clear"></div>
<script type="text/javascript">
var myMapper = new Mapper({parent: 'mapper-generic', zone: '{$position[0].atid}'});
$WH.gE($WH.ge('locations'), 'a')[0].onclick();
</script>
<?php
if (!empty($this->map)):
$this->brick('mapper');
else:
echo Lang::$gameObject['unkPosition'];
endif;

View File

@@ -1,89 +0,0 @@
{include file='header.tpl'}
<div id="main">
<div id="main-precontents"></div>
<div id="main-contents" class="main-contents">
<script type="text/javascript">
{include file='bricks/community.tpl'}
var g_pageInfo = {ldelim}type: {$page.type}, typeId: {$page.typeId}, name: '{$zone.name|escape:"quotes"}'{rdelim};
g_initPath({$page.path});
</script>
<div class="text">
<a href="{$wowhead}" class="button-red"><em><b><i>Wowhead</i></b><span>Wowhead</span></em></a>
<h1>{$zone.name}</h1>
{include file='bricks/article.tpl'}
{if $zone.position}
<div>
{strip}
<span id="locations">
{foreach from=$zone.position item=zoneitem name=zoneitem}
<a href="javascript:;" onclick="
myMapper.update(
{ldelim}
{if $zoneitem.atid}
zone:{$zoneitem.atid}
{if isset($zoneitem.points)}
,
{/if}
{else}
show:false
{/if}
{if isset($zoneitem.points)}
coords:[
{foreach from=$zoneitem.points item=point name=point}
[{$point.x},{$point.y},
{ldelim}
label:'{if isset($point.name)}{$point.name|escape:"html"|escape:"html"}{else}${/if}<br>
{if isset($point.r.h) or isset($point.r.m) or isset($point.r.s) or isset($point.events)}
<div class=q0>
<small>{$lang.respawn}:
{if isset($point.r.h)} {$point.r.h}{$lang.abbrHour}{/if}
{if isset($point.r.m)} {$point.r.m}{$lang.abbrMinute}{/if}
{if isset($point.r.s)} {$point.r.s}{$lang.abbrSecond}{/if}
{if isset($point.events)}<br>{$point.events|escape:"quotes"}{/if}
</small>
</div>
{/if}',
{if isset($point.url)}url:'{$point.url|escape:"quotes"}',{/if}
type:'{$point.type}'
{rdelim}]
{if !$smarty.foreach.point.last},{/if}
{/foreach}
]
{/if}
{rdelim});
g_setSelectedLink(this, 'mapper'); return false" onmousedown="return false">
{$zoneitem.name}</a>{if $zoneitem.population > 1}&nbsp;({$zoneitem.population}){/if}{if $smarty.foreach.zoneitem.last}{else}, {/if}
{/foreach}
</span></div>
{/strip}
<div id="mapper-generic"></div>
<div class="clear"></div>
<script type="text/javascript">
var myMapper = new Mapper({ldelim}parent: 'mapper-generic', zone: '{$zone.position[0].atid}'{rdelim});
$WH.gE($WH.ge('locations'), 'a')[0].onclick();
</script>
{/if}
{if isset($zone.parentname) and isset($zone.parent)}
<div class="pad"></div>
<div>{$lang.zonePartOf} <a href="?zone={$zone.parent}">{$zone.parentname}</a>.</div>
{/if}
<h2>{$lang.related}</h2>
</div>
{include file='bricks/tabsRelated.tpl' tabs=$lvData.relTabs}
{include file='bricks/contribute.tpl'}
</div>
</div>
</div>
{include file='footer.tpl'}