From bc7d561da2bb091643597777282d52a98a6be4d9 Mon Sep 17 00:00:00 2001 From: Sarjuuk Date: Mon, 1 Apr 2024 21:33:09 +0200 Subject: [PATCH] Core/Conditions * rewritten and moved to its own class, should be easier to expand in the future * add missing sources and types from TrinityCore * implement conditions on Areatrigger and Loot containers * implement reverse lookups (e.g. a spell is a conditional for something else) * general beautification pass .. should be more legible in general NOTE: * texts have been changed, so the existing translation for esES ist gone * selecting and describing condition targets is still wonky --- includes/basetype.class.php | 4 +- includes/conditions.class.php | 724 ++++++++++++++++++++++++++ includes/defines.php | 66 +-- includes/kernel.php | 3 +- includes/loot.class.php | 63 ++- includes/types/item.class.php | 6 +- includes/utilities.php | 143 ----- pages/achievement.php | 9 + pages/areatrigger.php | 9 + pages/currency.php | 19 +- pages/event.php | 26 +- pages/item.php | 89 +--- pages/npc.php | 149 ++---- pages/object.php | 49 +- pages/quest.php | 48 +- pages/sound.php | 2 +- pages/spell.php | 247 ++++----- pages/zone.php | 159 ++---- setup/tools/filegen/profiler.func.php | 8 +- static/js/global.js | 337 ++++++------ static/js/locale_dede.js | 210 ++++++-- static/js/locale_enus.js | 220 +++++--- static/js/locale_eses.js | 210 ++++++-- static/js/locale_frfr.js | 210 ++++++-- static/js/locale_ruru.js | 210 ++++++-- static/js/locale_zhcn.js | 210 ++++++-- 26 files changed, 2158 insertions(+), 1272 deletions(-) create mode 100644 includes/conditions.class.php diff --git a/includes/basetype.class.php b/includes/basetype.class.php index 9ce6bfaf..a00da8f4 100644 --- a/includes/basetype.class.php +++ b/includes/basetype.class.php @@ -859,9 +859,9 @@ trait sourceHelper protected $sources = []; protected $sourceMore = null; - public function getSources(?array &$s, ?array &$sm) : bool + public function getSources(?array &$s = [], ?array &$sm = []) : bool { - $s = $sm = null; + $s = $sm = []; if (empty($this->sources[$this->id])) return false; diff --git a/includes/conditions.class.php b/includes/conditions.class.php new file mode 100644 index 00000000..cd97abe0 --- /dev/null +++ b/includes/conditions.class.php @@ -0,0 +1,724 @@ + + public const OP_LT = 2; // < + public const OP_GT_E = 3; // >= + public const OP_LT_E = 4; // <= + // Group, Entry, Id + public const SRC_NONE = 0; // null, null, null - use when adding external conditions + public const SRC_CREATURE_LOOT_TEMPLATE = 1; // tplEntry, itemId, null + public const SRC_DISENCHANT_LOOT_TEMPLATE = 2; // tplEntry, itemId, null + public const SRC_FISHING_LOOT_TEMPLATE = 3; // tplEntry, itemId, null + public const SRC_GAMEOBJECT_LOOT_TEMPLATE = 4; // tplEntry, itemId, null + public const SRC_ITEM_LOOT_TEMPLATE = 5; // tplEntry, itemId, null + public const SRC_MAIL_LOOT_TEMPLATE = 6; // tplEntry, itemId, null + public const SRC_MILLING_LOOT_TEMPLATE = 7; // tplEntry, itemId, null + public const SRC_PICKPOCKETING_LOOT_TEMPLATE = 8; // tplEntry, itemId, null + public const SRC_PROSPECTING_LOOT_TEMPLATE = 9; // tplEntry, itemId, null + public const SRC_REFERENCE_LOOT_TEMPLATE = 10; // tplEntry, itemId, null + public const SRC_SKINNING_LOOT_TEMPLATE = 11; // tplEntry, itemId, null + public const SRC_SPELL_LOOT_TEMPLATE = 12; // tplEntry, itemId, null + public const SRC_SPELL_IMPLICIT_TARGET = 13; // effectMask, spellId, null + public const SRC_GOSSIP_MENU = 14; // menuId, textId, null + public const SRC_GOSSIP_MENU_OPTION = 15; // menuId, optionId, null + public const SRC_CREATURE_TEMPLATE_VEHICLE = 16; // npcId, null, null + public const SRC_SPELL = 17; // null, spellId, null + public const SRC_SPELL_CLICK_EVENT = 18; // npcId, spellId, null + public const SRC_QUEST_AVAILABLE = 19; // null, questId, null + public const SRC_QUEST_SHOW_MARK = 20; // null, questId, null - ⚠️ unused as of 01.05.2024 + public const SRC_VEHICLE_SPELL = 21; // npcId, spellId, null + public const SRC_SMART_EVENT = 22; // id, entryGuid, srcType + public const SRC_NPC_VENDOR = 23; // npcId, itemId, null + public const SRC_SPELL_PROC = 24; // null, spellId, null +// public const SRC_SPELL_TERRAIN_SWAP = 25; // - ❌ reserved for TC master +// public const SRC_SPELL_PHASE = 26; // - ❌ reserved for TC master +// public const SRC_SPELL_GRAVEYARD = 27; // - ❌ reserved for TC master +// public const SRC_SPELL_AREATRIGGER = 28; // - ❌ reserved for TC master +// public const SRC_SPELL_CONVERSATION_LINE = 29; // - ❌ reserved for TC master + public const SRC_AREATRIGGER_CLIENT = 30; // null, atId, null +// public const SRC_SPELL_TRAINER_SPELL = 31; // - ❌ reserved for TC master +// public const SRC_SPELL_OBJECT_VISIBILITY = 32; // - ❌ reserved for TC master +// public const SRC_SPELL_SPAWN_GROUP = 33; // - ❌ reserved for TC master + + public const NONE = 0; // always true: NULL, NULL, NULL + public const AURA = 1; // aura is applied: spellId, effIdx, NULL + public const ITEM = 2; // owns item: itemId, count, includeBank? + public const ITEM_EQUIPPED = 3; // has item equipped: itemId, NULL, NULL + public const ZONEID = 4; // is in zone: areaId, NULL, NULL + public const REPUTATION_RANK = 5; // reputation status: factionId, rankMask, NULL + public const TEAM = 6; // is on team: teamId, NULL, NULL + public const SKILL = 7; // has skill: skillId, value, NULL + public const QUESTREWARDED = 8; // has finished quest: questId, NULL, NULL + public const QUESTTAKEN = 9; // has accepted quest: questId, NULL, NULL + public const DRUNKENSTATE = 10; // has drunken status: stateId, NULL, NULL + public const WORLD_STATE = 11; // world var == value: worldStateId, value, NULL + public const ACTIVE_EVENT = 12; // world event is active: eventId, NULL, NULL + public const INSTANCE_INFO = 13; // instance var == data: entry data, type + public const QUEST_NONE = 14; // never seen quest: questId, NULL, NULL + public const CHR_CLASS = 15; // belongs to classes: classMask, NULL, NULL + public const CHR_RACE = 16; // belongs to races: raceMask, NULL, NULL + public const ACHIEVEMENT = 17; // obtained achievement: achievementId, NULL, NULL + public const TITLE = 18; // obtained title: titleId, NULL, NULL + public const SPAWNMASK = 19; // spawnMask, NULL, NULL + public const GENDER = 20; // has gender: genderId, NULL, NULL + public const UNIT_STATE = 21; // unit has state: unitState, NULL, NULL + public const MAPID = 22; // is on map: mapId, NULL, NULL + public const AREAID = 23; // is in area: areaId, NULL, NULL + public const CREATURE_TYPE = 24; // creature is of type: creaturetypeId, NULL, NULL + public const SPELL = 25; // knows spell: spellId, NULL, NULL + public const PHASEMASK = 26; // is in phase: phaseMask, NULL, NULL + public const LEVEL = 27; // player level is..: level, comparator, NULL + public const QUEST_COMPLETE = 28; // has completed quest: questId, NULL, NULL + public const NEAR_CREATURE = 29; // is near creature: creatureId, dist, includeCorpse? + public const NEAR_GAMEOBJECT = 30; // is near gameObject: gameObjectId, dist, NULL + public const OBJECT_ENTRY_GUID = 31; // target is ???: objectType, id, guid + public const TYPE_MASK = 32; // target matches type: typeMask, NULL, NULL + public const RELATION_TO = 33; // Cond.Target, relation, NULL + public const REACTION_TO = 34; // Cond.Target, rankMask, NULL + public const DISTANCE_TO = 35; // distance to target Cond.Target, dist, comparator + public const ALIVE = 36; // target is alive: NULL, NULL, NULL + public const HP_VAL = 37; // targets absolute health: amount, comparator, NULL + public const HP_PCT = 38; // targets relative health: amount, comparator, NULL + public const REALM_ACHIEVEMENT = 39; // realmfirst was achieved: achievementId, NULL, NULL + public const IN_WATER = 40; // unit is swimming: NULL, NULL, NULL +// public const TERRAIN_SWAP = 41; // ❌ reserved for TC master + public const STAND_STATE = 42; // stateType, state, NULL + public const DAILY_QUEST_DONE = 43; // repeatable quest done: questId, NULL, NULL + public const CHARMED = 44; // unit is charmed: NULL, NULL, NULL + public const PET_TYPE = 45; // player has pet of type: petType, NULL, NULL + public const TAXI = 46; // player is on taxi: NULL, NULL, NULL + public const QUESTSTATE = 47; // questId, stateMask, NULL + public const QUEST_OBJECTIVE_PROGRESS = 48; // questId, objectiveIdx, count + public const DIFFICULTY_ID = 49; // map has difficulty id: difficulty, NULL, NULL + public const GAMEMASTER = 50; // player is GM: canBeGM?, NULL, NULL +// public const OBJECT_ENTRY_GUID_MASTER = 51; // ❌ reserved for TC master +// public const TYPE_MASK_MASTER = 52; // ❌ reserved for TC master +// public const BATTLE_PET_COUNT = 53; // ❌ reserved for TC master +// public const SCENARIO_STEP = 54; // ❌ reserved for TC master +// public const SCENE_IN_PROGRESS = 55; // ❌ reserved for TC master +// public const PLAYER_CONDITION = 56; // ❌ reserved for TC master + + private const IDX_SRC_GROUP = 0; + private const IDX_SRC_ENTRY = 1; + private const IDX_SRC_ID = 2; + private const IDX_SRC_FN = 3; + + private static $source = array( // [Group, Entry, Id] + self::SRC_NONE => [null, null, null, null], + self::SRC_CREATURE_LOOT_TEMPLATE => [Type::NPC, Type::ITEM, null, 'lootIdToNpc'], + self::SRC_DISENCHANT_LOOT_TEMPLATE => [Type::ITEM, Type::ITEM, null, 'disenchantIdToItem'], + self::SRC_FISHING_LOOT_TEMPLATE => [Type::ZONE, Type::ITEM, null, null], + self::SRC_GAMEOBJECT_LOOT_TEMPLATE => [Type::OBJECT, Type::ITEM, null, 'lootIdToGObject'], + self::SRC_ITEM_LOOT_TEMPLATE => [Type::ITEM, Type::ITEM, null, null], + self::SRC_MAIL_LOOT_TEMPLATE => [Type::QUEST, Type::ITEM, null, 'RewardTemplateToQuest'], + self::SRC_MILLING_LOOT_TEMPLATE => [Type::ITEM, Type::ITEM, null, null], + self::SRC_PICKPOCKETING_LOOT_TEMPLATE => [Type::NPC, Type::ITEM, null, 'PickpocketLootToNpc'], + self::SRC_PROSPECTING_LOOT_TEMPLATE => [Type::ITEM, Type::ITEM, null, null], + self::SRC_REFERENCE_LOOT_TEMPLATE => [null, Type::ITEM, null, null], + self::SRC_SKINNING_LOOT_TEMPLATE => [Type::NPC, Type::ITEM, null, 'SkinLootToNpc'], + self::SRC_SPELL_LOOT_TEMPLATE => [Type::SPELL, Type::ITEM, null, null], + self::SRC_SPELL_IMPLICIT_TARGET => [true, Type::SPELL, null, null], + self::SRC_GOSSIP_MENU => [true, true, null, null], + self::SRC_GOSSIP_MENU_OPTION => [true, true, null, null], + self::SRC_CREATURE_TEMPLATE_VEHICLE => [null, Type::NPC, null, null], + self::SRC_SPELL => [null, Type::SPELL, null, null], + self::SRC_SPELL_CLICK_EVENT => [Type::NPC, Type::SPELL, null, null], + self::SRC_QUEST_AVAILABLE => [null, Type::QUEST, null, null], + self::SRC_QUEST_SHOW_MARK => [null, Type::QUEST, null, null], + self::SRC_VEHICLE_SPELL => [Type::NPC, Type::SPELL, null, null], + self::SRC_SMART_EVENT => [true, true, true, null], + self::SRC_NPC_VENDOR => [Type::NPC, Type::ITEM, null, null], + self::SRC_SPELL_PROC => [null, Type::SPELL, null, null], + self::SRC_AREATRIGGER_CLIENT => [null, true, null, null] + ); + + private const IDX_CND_VAL1 = 0; + private const IDX_CND_VAL2 = 1; + private const IDX_CND_VAL3 = 2; + private const IDX_CND_FN = 3; + + private static $conditions = array(// [Value1, Value2, Value3, handlerFn] + self::NONE => [null, null, null, null], + self::AURA => [Type::SPELL, null, null, null], + self::ITEM => [Type::ITEM, true, true, null], + self::ITEM_EQUIPPED => [Type::ITEM, null, null, null], + self::ZONEID => [Type::ZONE, null, null, null], + self::REPUTATION_RANK => [Type::FACTION, true, null, null], + self::TEAM => [true, null, null, 'factionToSide'], + self::SKILL => [Type::SKILL, true, null, null], + self::QUESTREWARDED => [Type::QUEST, null, null, null], + self::QUESTTAKEN => [Type::QUEST, null, null, null], + self::DRUNKENSTATE => [true, null, null, null], + self::WORLD_STATE => [true, true, null, null], + self::ACTIVE_EVENT => [Type::WORLDEVENT, null, null, null], + self::INSTANCE_INFO => [true, true, true, null], + self::QUEST_NONE => [Type::QUEST, null, null, null], + self::CHR_CLASS => [Type::CHR_CLASS, null, null, 'maskToBits'], + self::CHR_RACE => [Type::CHR_RACE, null, null, 'maskToBits'], + self::ACHIEVEMENT => [Type::ACHIEVEMENT, null, null, null], + self::TITLE => [Type::TITLE, null, null, null], + self::SPAWNMASK => [true, null, null, null], + self::GENDER => [true, null, null, null], + self::UNIT_STATE => [true, null, null, null], + self::MAPID => [true, true, null, 'mapToZone'], + self::AREAID => [Type::ZONE, null, null, null], + self::CREATURE_TYPE => [true, null, null, null], + self::SPELL => [Type::SPELL, null, null, null], + self::PHASEMASK => [true, null, null, null], + self::LEVEL => [true, true, null, null], + self::QUEST_COMPLETE => [Type::QUEST, null, null, null], + self::NEAR_CREATURE => [Type::NPC, true, true, null], + self::NEAR_GAMEOBJECT => [Type::OBJECT, true, true, null], + self::OBJECT_ENTRY_GUID => [true, true, true, 'typeidToId'], + self::TYPE_MASK => [true, null, null, null], + self::RELATION_TO => [true, true, null, null], + self::REACTION_TO => [true, true, null, null], + self::DISTANCE_TO => [true, true, true, null], + self::ALIVE => [null, null, null, null], + self::HP_VAL => [true, true, null, null], + self::HP_PCT => [true, true, null, null], + self::REALM_ACHIEVEMENT => [Type::ACHIEVEMENT, null, null, null], + self::IN_WATER => [null, null, null, null], + self::STAND_STATE => [true, true, null, null], + self::DAILY_QUEST_DONE => [Type::QUEST, null, null, null], + self::CHARMED => [null, null, null, null], + self::PET_TYPE => [true, null, null, null], + self::TAXI => [null, null, null, null], + self::QUESTSTATE => [Type::QUEST, true, null, null], + self::QUEST_OBJECTIVE_PROGRESS => [Type::QUEST, true, true, null], + self::DIFFICULTY_ID => [true, null, null, null], + self::GAMEMASTER => [true, null, null, null] + ); + + private $jsGlobals = []; + private $rows = []; + private $result = []; + private $resultExtra = []; + + + /******/ + /* IN */ + /******/ + + public function getBySourceEntry(int $entry, int ...$srcType) : bool + { + $this->rows = DB::World()->select( + 'SELECT `SourceTypeOrReferenceId`, `SourceEntry`, `SourceGroup`, `SourceId`, `ElseGroup`, + `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition` + FROM conditions + WHERE `SourceTypeOrReferenceId` IN (?a) AND `SourceEntry` = ?d + ORDER BY `SourceTypeOrReferenceId`, `SourceEntry`, `SourceGroup`, `ElseGroup` ASC', + $srcType, $entry + ); + + return $this->fromSource(); + } + + public function getBySourceGroup(int $group, int ...$srcType) : bool + { + $this->rows = DB::World()->select( + 'SELECT `SourceTypeOrReferenceId`, `SourceEntry`, `SourceGroup`, `SourceId`, `ElseGroup`, + `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition` + FROM conditions + WHERE `SourceTypeOrReferenceId` IN (?a) AND `SourceGroup` = ?d + ORDER BY `SourceTypeOrReferenceId`, `SourceEntry`, `SourceGroup`, `ElseGroup` ASC', + $srcType, $group + ); + + return $this->fromSource(); + } + + public function getByCondition(int $type, int $typeId/* , int ...$conditionIds */) : bool + { + $lookups = []; // can only be in val1 for now + foreach (self::$conditions as $cId => [$cVal1, , , ]) + if ($type === $cVal1 /* && (!$conditionIds || in_array($cId, $conditionIds)) */ ) + $lookups[] = sprintf("(c2.`ConditionTypeOrReference` = %d AND c2.`ConditionValue1` = %d)", $cId, $typeId); + + if (!$lookups) + return false; + + $this->rows = DB::World()->select(sprintf( + 'SELECT c1.`SourceTypeOrReferenceId`, c1.`SourceEntry`, c1.`SourceGroup`, c1.`SourceId`, c1.`ElseGroup`, + c1.`ConditionTypeOrReference`, c1.`ConditionTarget`, c1.`ConditionValue1`, c1.`ConditionValue2`, c1.`ConditionValue3`, c1.`NegativeCondition` + FROM conditions c1 + JOIN conditions c2 ON c1.SourceTypeOrReferenceId = c2.SourceTypeOrReferenceId AND c1.SourceEntry = c2.SourceEntry AND c1.SourceGroup = c2.SourceGroup AND c1.SourceId = c2.SourceId + WHERE %s + ORDER BY `SourceTypeOrReferenceId`, `SourceEntry`, `SourceGroup`, `ElseGroup` ASC' + , implode(' OR ', $lookups))); + + return $this->fromSource(); + } + + public function addExternalCondition(int $srcType, string $groupKey, array $condition, bool $orGroup = false) : void + { + if (!isset(self::$source[$srcType])) + return; + + [$cId, $cVal1, $cVal2, $cVal3] = array_pad($condition, 5, 0); + if (!isset(self::$conditions[abs($cId)])) + return; + + while (substr_count($groupKey, ':') < 3) + $groupKey .= ':0'; // pad with missing srcEntry, SrcId, cndTarget to group key + + if ($c = $this->prepareCondition($cId, $cVal1, $cVal2, $cVal3)) + { + if ($orGroup) + $this->result[$srcType][$groupKey][] = [$c]; + else if (!isset($this->result[$srcType][$groupKey][0])) + $this->result[$srcType][$groupKey][0] = [$c]; + else + $this->result[$srcType][$groupKey][0][] = $c; + } + } + + + /*******/ + /* OUT */ + /*******/ + + public function toListviewTab(string $id = 'conditions', string $name = '') : array + { + if (!$this->result) + return []; + + $out = []; + $nCnd = 0; + foreach ($this->result as $srcType => $srcData) + { + foreach ($srcData as $grpKey => $grpData) + { + if (!isset($this->resultExtra[$srcType][$grpKey])) + { + $nCnd++; + $out[$srcType][$grpKey] = $grpData; + } + else + { + $nCnd += count($this->resultExtra[$srcType][$grpKey]); + foreach ($this->resultExtra[$srcType][$grpKey] as $extraGrp) + $out[$srcType][$extraGrp] = $grpData; + } + } + } + + $data = ""; + + $tab = array( + 'data' => $data, + 'id' => $id, + 'name' => ($name ?: '$LANG.tab_conditions') . '+" ('.$nCnd.')"' + ); + + return [null, $tab]; + } + + public function toListviewColumn(array &$lvRows, ?array &$extraCols = [], int $srcEntry = 0) : bool + { + if (!$this->result) + return false; + + $success = false; + foreach ($lvRows as $key => &$row) + { + $key = $row['id'].':'.$srcEntry; // it's a listview row .. if it doesn't have a numeric id something truely fucked up happened. ... also its past 2a.m. + while (substr_count($key, ':') < 3) // pad with missing srcEntry, SrcId, cndTarget to group key + $key .= ':0'; + + foreach ($this->result as $cndData) + { + if (empty($cndData[$key])) + continue; + + $row['condition'][self::SRC_NONE][$key] = $cndData[$key]; + $success = true; + } + } + + if ($success) + $extraCols[] = '$Listview.extraCols.condition'; + + return $success; + } + + public function getJsGlobals() : array + { + return $this->jsGlobals; + } + + + /*********/ + /* Other */ + /*********/ + + public static function lootTableToConditionSource(string $lootTable) : int + { + switch ($lootTable) + { + case LOOT_FISHING: return self::SRC_FISHING_LOOT_TEMPLATE; + case LOOT_CREATURE: return self::SRC_CREATURE_LOOT_TEMPLATE; + case LOOT_GAMEOBJECT: return self::SRC_GAMEOBJECT_LOOT_TEMPLATE; + case LOOT_ITEM: return self::SRC_ITEM_LOOT_TEMPLATE; + case LOOT_DISENCHANT: return self::SRC_DISENCHANT_LOOT_TEMPLATE; + case LOOT_PROSPECTING: return self::SRC_PROSPECTING_LOOT_TEMPLATE; + case LOOT_MILLING: return self::SRC_MILLING_LOOT_TEMPLATE; + case LOOT_PICKPOCKET: return self::SRC_PICKPOCKETING_LOOT_TEMPLATE; + case LOOT_SKINNING: return self::SRC_SKINNING_LOOT_TEMPLATE; + case LOOT_MAIL: return self::SRC_MAIL_LOOT_TEMPLATE; + case LOOT_SPELL: return self::SRC_SPELL_LOOT_TEMPLATE; + case LOOT_REFERENCE: return self::SRC_REFERENCE_LOOT_TEMPLATE; + default: return self::SRC_NONE; + } + } + + public static function extendListviewRow(array &$lvRow, int $srcType, int $groupKey, array $condition) : bool + { + if (!isset(self::$source[$srcType])) + return false; + + [$cId, $cVal1, $cVal2, $cVal3] = array_pad($condition, 5, 0); + if (!isset(self::$conditions[abs($cId)])) + return false; + + while (substr_count($groupKey, ':') < 3) + $groupKey .= ':0'; // pad with missing srcEntry, SrcId, cndTarget to group key + + if ($c = (new self())->prepareCondition($cId, $cVal1, $cVal2, $cVal3)) + $lvRow['condition'][$srcType][$groupKey][] = [$c]; + + return true; + } + + private function fromSource() : bool + { + // itr over rows and prep data + if (!$this->rows) + return !empty($this->result); // respect previously added externalCnd + + foreach ($this->rows as $r) + { + if (!isset(self::$source[$r['SourceTypeOrReferenceId']])) + { + trigger_error('Conditions: skipping condition with unknown SourceTypeOrReferenceId #'.$r['SourceTypeOrReferenceId'], E_USER_WARNING); + continue; + } + + if (!isset(self::$conditions[$r['ConditionTypeOrReference']])) + { + trigger_error('Conditions: skipping condition with unknown ConditionTypeOrReference #'.$r['ConditionTypeOrReference'], E_USER_WARNING); + continue; + } + + [$sType, $sGroup, $sEntry, $sId, $cTarget] = $this->prepareSource($r['SourceTypeOrReferenceId'], $r['SourceGroup'], $r['SourceEntry'], $r['SourceId'], $r['ConditionTarget']); + if ($sType === null) + continue; + + $cnd = $this->prepareCondition( + $r['NegativeCondition'] ? -$r['ConditionTypeOrReference'] : $r['ConditionTypeOrReference'], + $r['ConditionValue1'], + $r['ConditionValue2'], + $r['ConditionValue3'] + ); + if (!$cnd) + continue; + + $group = $sGroup . ':' . $sEntry . ':' . $sId . ':' . $cTarget; + $this->result[$r['SourceTypeOrReferenceId']] [$group] [$r['ElseGroup']] [] = $cnd; + } + + return true; + } + + private function prepareSource(int $sType, int $sGroup, int $sEntry, int $sId, int $cTarget) : array + { + // only one entry in array expected + if ($fn = self::$source[$sType][self::IDX_SRC_FN]) + if (!$this->$fn($sType, $sGroup, $sEntry, $sId, $cTarget)) + return [null, null, null, null, null]; + + [$grp, $entry, $id, $_] = self::$source[$sType]; + if (is_int($grp)) + $this->jsGlobals[$grp][$sGroup] = $sGroup; + if (is_int($entry)) + $this->jsGlobals[$entry][$sEntry] = $sEntry; + // Note: sourceId currently has no typed content + // if (is_int($id)) + // $this->jsGlobals[$id][$sId] = $sId; + + // more checks? not all sources can retarget + $cTarget = min(1, max(0, $cTarget)); + + return [$sType, $sGroup, $sEntry, $sId, $cTarget]; + } + + private function prepareCondition($cId, $cVal1, $cVal2, $cVal3) : array + { + if ($fn = self::$conditions[abs($cId)][self::IDX_CND_FN]) + if (!$this->$fn(abs($cId), $cVal1, $cVal2, $cVal3)) + return []; + + $result = [$cId]; + + for ($i = 0; $i < 3; $i++) + { + $field = self::$conditions[abs($cId)][$i]; + + if (is_int($field)) + $this->jsGlobals[$field][${'cVal'.($i+1)}] = ${'cVal'.($i+1)}; + if ($field) + $result[] = ${'cVal'.($i+1)}; // variable amount of condition values + } + + return $result; + } + + private function factionToSide($cId, &$cVal1, $cVal2, $cVal3) : bool + { + if ($cVal1 == 469) + $cVal1 = SIDE_ALLIANCE; + else if ($cVal1 == 67) + $cVal1 = SIDE_HORDE; + else + $cVal1 = SIDE_BOTH; + + return true; + } + + private function mapToZone($cId, &$cVal1, &$cVal2, $cVal3) : bool + { + // use g_zone_categories id + if ($cVal1 == 530) // outland + $cVal1 = 8; + else if ($cVal1 == 571) // northrend + $cVal1 = 10; + else if ($cVal1 == 0 || $cVal1 == 1) // eastern kingdoms / kalimdor + ; // cVal alrady correct - NOP + else if ($id = DB::Aowow()->selectCell('SELECT `id` FROM ?_zones WHERE `mapId` = ?d AND `parentArea` = 0 AND (`cuFlags` & ?d) = 0', $cVal1, CUSTOM_EXCLUDE_FOR_LISTVIEW)) + { + // remap for instanced area - do not use List (pointless overhead) + $this->jsGlobals[Type::ZONE][$id] = $id; + $cVal2 = $id; + $cVal1 = 0; + } + else + { + trigger_error('Conditions - CONDITION_MAPID has invalid mapId #'.$cVal1, E_USER_WARNING); + return false; + } + + return true; + } + + private function maskToBits($cId, &$cVal1, $cVal2, $cVal3) : bool + { + if ($cId == self::CHR_CLASS) + { + $cVal1 &= CLASS_MASK_ALL; + foreach (Util::mask2bits($cVal1, 1) as $cId) + $this->jsGlobals[Type::CHR_CLASS][$cId] = $cId; + } + + if ($cId == self::CHR_RACE) + { + $cVal1 &= RACE_MASK_ALL; + foreach (Util::mask2bits($cVal1, 1) as $rId) + $this->jsGlobals[Type::CHR_RACE][$rId] = $rId; + } + + return true; + } + + private function typeidToId($cId, $cVal1, &$cVal2, &$cVal3) : bool + { + if ($cVal1 == self::TYPEID_UNIT) + { + if ($cVal3 && ($_ = DB::Aowow()->selectCell('SELECT `typeId` FROM ?_spawns WHERE `type` = ?d AND `guid` = ?d', Type::NPC, $cVal3))) + $cVal2 = intVal($_); + + if ($cVal2) + $this->jsGlobals[Type::NPC][$cVal2] = $cVal2; + } + else if ($cVal1 == self::TYPEID_GAMEOBJECT) + { + if ($cVal3 && ($_ = DB::Aowow()->selectCell('SELECT `typeId` FROM ?_spawns WHERE `type` = ?d AND `guid` = ?d', Type::OBJECT, $cVal3))) + $cVal2 = intVal($_); + + if ($cVal2) + $this->jsGlobals[Type::OBJECT][$cVal2] = $cVal2; + } + else // Player or Corpse .. no guid + $cVal2 = $cVal3 = 0; + + // maybe prepare other types? + return true; + } + + private function lootIdToNpc(int $sType, int $sGroup, int $sEntry, int $sId, int $cTarget) : bool + { + if (!$sGroup) + { + trigger_error('Conditions::lootToNpc - skipping reference to creature_loot_template entry 0', E_USER_WARNING); + return false; + } + + if ($npcs = DB::Aowow()->selectCol('SELECT `id` FROM ?_creature WHERE `lootId` = ?d', $sGroup)) + { + $group = $sGroup . ':' . $sEntry . ':' . $sId . ':' . $cTarget; + foreach ($npcs as $npcId) + { + $this->jsGlobals[Type::NPC][$npcId] = $npcId; + $this->resultExtra[$sType][$group][] = $npcId . ':' . $sEntry . ':' . $sId . ':' . $cTarget; + } + + return true; + } + + trigger_error('Conditions::lootToNpc - creature_loot_template #'.$sGroup.' unreferenced?', E_USER_WARNING); + return false; + } + + private function disenchantIdToItem(int $sType, int $sGroup, int $sEntry, int $sId, int $cTarget) : bool + { + if (!$sGroup) + { + trigger_error('Conditions::disenchantIdToItem - skipping reference to disenchant_loot_template entry 0', E_USER_WARNING); + return false; + } + + if ($items = DB::Aowow()->selectCol('SELECT `id` FROM ?_items WHERE `disenchantId` = ?d', $sGroup)) + { + $group = $sGroup . ':' . $sEntry . ':' . $sId . ':' . $cTarget; + foreach ($items as $itemId) + { + $this->jsGlobals[Type::ITEM][$itemId] = $itemId; + $this->resultExtra[$sType][$group][] = $itemId . ':' . $sEntry . ':' . $sId . ':' . $cTarget; + } + + return true; + } + + trigger_error('Conditions::disenchantIdToItem - disenchant_loot_template #'.$sGroup.' unreferenced?', E_USER_WARNING); + return false; + } + + private function lootIdToGObject(int $sType, int $sGroup, int $sEntry, int $sId, int $cTarget) : bool + { + if (!$sGroup) + { + trigger_error('Conditions::lootIdToGObject - skipping reference to gameobject_loot_template entry 0', E_USER_WARNING); + return false; + } + + if ($gos = DB::Aowow()->selectCol('SELECT `id` FROM ?_objects WHERE `lootId` = ?d', $sGroup)) + { + $group = $sGroup . ':' . $sEntry . ':' . $sId . ':' . $cTarget; + foreach ($gos as $goId) + { + $this->jsGlobals[Type::OBJECT][$goId] = $goId; + $this->resultExtra[$sType][$group][] = $goId . ':' . $sEntry . ':' . $sId . ':' . $cTarget; + } + + return true; + } + + trigger_error('Conditions::lootIdToGObject - gameobject_loot_template #'.$sGroup.' unreferenced?', E_USER_WARNING); + return false; + } + + private function RewardTemplateToQuest(int $sType, int $sGroup, int $sEntry, int $sId, int $cTarget) : bool + { + if (!$sGroup) + { + trigger_error('Conditions::RewardTemplateToQuest - skipping reference to mail_loot_template entry 0', E_USER_WARNING); + return false; + } + + if ($quests = DB::Aowow()->selectCol('SELECT `id` FROM ?_quests WHERE `rewardMailTemplateId` = ?d', $sGroup)) + { + $group = $sGroup . ':' . $sEntry . ':' . $sId . ':' . $cTarget; + foreach ($quests as $questId) + { + $this->jsGlobals[Type::QUEST][$questId] = $questId; + $this->resultExtra[$sType][$group][] = $questId . ':' . $sEntry . ':' . $sId . ':' . $cTarget; + } + + return true; + } + + trigger_error('Conditions::RewardTemplateToQuest - mail_loot_template #'.$sGroup.' unreferenced?', E_USER_WARNING); + return false; + } + + private function PickpocketLootToNpc(int $sType, int $sGroup, int $sEntry, int $sId, int $cTarget) : bool + { + if (!$sGroup) + { + trigger_error('Conditions::PickpocketLootToNpc - skipping reference to pickpocketing_loot_template entry 0', E_USER_WARNING); + return false; + } + + if ($npcs = DB::Aowow()->selectCol('SELECT `id` FROM ?_creature WHERE `pickpocketLootId` = ?d', $sGroup)) + { + $group = $sGroup . ':' . $sEntry . ':' . $sId . ':' . $cTarget; + foreach ($npcs as $npcId) + { + $this->jsGlobals[Type::NPC][$npcId] = $npcId; + $this->resultExtra[$sType][$group][] = $npcId . ':' . $sEntry . ':' . $sId . ':' . $cTarget; + } + + return true; + } + + trigger_error('Conditions::PickpocketLootToNpc - pickpocketing_loot_template #'.$sGroup.' unreferenced?', E_USER_WARNING); + return false; + } + + private function SkinLootToNpc(int $sType, int $sGroup, int $sEntry, int $sId, int $cTarget) : bool + { + if (!$sGroup) + { + trigger_error('Conditions::SkinLootToNpc - skipping reference to skinning_loot_template entry 0', E_USER_WARNING); + return false; + } + + if ($npcs = DB::Aowow()->selectCol('SELECT `id` FROM ?_creature WHERE `skinLootId` = ?d', $sGroup)) + { + $group = $sGroup . ':' . $sEntry . ':' . $sId . ':' . $cTarget; + foreach ($npcs as $npcId) + { + $this->jsGlobals[Type::NPC][$npcId] = $npcId; + $this->resultExtra[$sType][$group][] = $npcId . ':' . $sEntry . ':' . $sId . ':' . $cTarget; + } + + return true; + } + + trigger_error('Conditions::SkinLootToNpc - skinning_loot_template #'.$sGroup.' unreferenced?', E_USER_WARNING); + return false; + } +} + +?> diff --git a/includes/defines.php b/includes/defines.php index 1efd4a55..a44422bc 100644 --- a/includes/defines.php +++ b/includes/defines.php @@ -1774,71 +1774,6 @@ define('ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE', 112); // define('ACHIEVEMENT_CRITERIA_TYPE_DISENCHANT_ROLLS', 117); // define('ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS', 119); -// TrinityCore - Condition System -define('CND_SRC_CREATURE_LOOT_TEMPLATE', 1); -define('CND_SRC_DISENCHANT_LOOT_TEMPLATE', 2); -define('CND_SRC_FISHING_LOOT_TEMPLATE', 3); -define('CND_SRC_GAMEOBJECT_LOOT_TEMPLATE', 4); -define('CND_SRC_ITEM_LOOT_TEMPLATE', 5); -define('CND_SRC_MAIL_LOOT_TEMPLATE', 6); -define('CND_SRC_MILLING_LOOT_TEMPLATE', 7); -define('CND_SRC_PICKPOCKETING_LOOT_TEMPLATE', 8); -define('CND_SRC_PROSPECTING_LOOT_TEMPLATE', 9); -define('CND_SRC_REFERENCE_LOOT_TEMPLATE', 10); -define('CND_SRC_SKINNING_LOOT_TEMPLATE', 11); -define('CND_SRC_SPELL_LOOT_TEMPLATE', 12); -define('CND_SRC_SPELL_IMPLICIT_TARGET', 13); -define('CND_SRC_GOSSIP_MENU', 14); -define('CND_SRC_GOSSIP_MENU_OPTION', 15); -define('CND_SRC_CREATURE_TEMPLATE_VEHICLE', 16); -define('CND_SRC_SPELL', 17); -define('CND_SRC_SPELL_CLICK_EVENT', 18); -define('CND_SRC_QUEST_ACCEPT', 19); -define('CND_SRC_QUEST_SHOW_MARK', 20); -define('CND_SRC_VEHICLE_SPELL', 21); -define('CND_SRC_SMART_EVENT', 22); -define('CND_SRC_NPC_VENDOR', 23); -define('CND_SRC_SPELL_PROC', 24); - -define('CND_AURA', 1); // aura is applied: spellId, UNUSED, NULL -define('CND_ITEM', 2); // owns item: itemId, count, UNUSED -define('CND_ITEM_EQUIPPED', 3); // has item equipped: itemId, NULL, NULL -define('CND_ZONEID', 4); // is in zone: areaId, NULL, NULL -define('CND_REPUTATION_RANK', 5); // reputation status: factionId, rankMask, NULL -define('CND_TEAM', 6); // is on team: teamId, NULL, NULL -define('CND_SKILL', 7); // has skill: skillId, value, NULL -define('CND_QUESTREWARDED', 8); // has finished quest: questId, NULL, NULL -define('CND_QUESTTAKEN', 9); // has accepted quest: questId, NULL, NULL -define('CND_DRUNKENSTATE', 10); // has drunken status: stateId, NULL, NULL -define('CND_WORLD_STATE', 11); -define('CND_ACTIVE_EVENT', 12); // world event is active: eventId, NULL, NULL -define('CND_INSTANCE_INFO', 13); -define('CND_QUEST_NONE', 14); // never seen quest: questId, NULL, NULL -define('CND_CLASS', 15); // belongs to classes: classMask, NULL, NULL -define('CND_RACE', 16); // belongs to races: raceMask, NULL, NULL -define('CND_ACHIEVEMENT', 17); // obtained achievement: achievementId, NULL, NULL -define('CND_TITLE', 18); // obtained title: titleId, NULL, NULL -define('CND_SPAWNMASK', 19); -define('CND_GENDER', 20); // has gender: genderId, NULL, NULL -define('CND_UNIT_STATE', 21); -define('CND_MAPID', 22); // is on map: mapId, NULL, NULL -define('CND_AREAID', 23); // is in area: areaId, NULL, NULL -define('CND_UNUSED_24', 24); -define('CND_SPELL', 25); // knows spell: spellId, NULL, NULL -define('CND_PHASEMASK', 26); // is in phase: phaseMask, NULL, NULL -define('CND_LEVEL', 27); // player level is..: level, operator, NULL -define('CND_QUEST_COMPLETE', 28); // has completed quest: questId, NULL, NULL -define('CND_NEAR_CREATURE', 29); // is near creature: creatureId, dist, NULL -define('CND_NEAR_GAMEOBJECT', 30); // is near gameObject: gameObjectId, dist, NULL -define('CND_OBJECT_ENTRY', 31); // target is ???: objectType, id, NULL -define('CND_TYPE_MASK', 32); // target is type: typeMask, NULL, NULL -define('CND_RELATION_TO', 33); -define('CND_REACTION_TO', 34); -define('CND_DISTANCE_TO', 35); // distance to target targetType, dist, operator -define('CND_ALIVE', 36); // target is alive: NULL, NULL, NULL -define('CND_HP_VAL', 37); // targets absolute health: amount, operator, NULL -define('CND_HP_PCT', 38); // targets relative health: amount, operator, NULL - // TrinityCore - SmartAI define('SAI_SRC_TYPE_CREATURE', 0); define('SAI_SRC_TYPE_OBJECT', 1); @@ -2250,4 +2185,5 @@ define('EMOTE_FLAG_END_MOVEMENT', 0x1000); // Movement ends define('EMOTE_FLAG_INTERRUPT_ON_ATTACK', 0x2000); // Interrupt on attack define('EMOTE_FLAG_ONLY_STILL', 0x4000); // Only while still define('EMOTE_FLAG_NOT_FLYING', 0x8000); // Not while flying + ?> diff --git a/includes/kernel.php b/includes/kernel.php index f0089481..be8a6ae5 100644 --- a/includes/kernel.php +++ b/includes/kernel.php @@ -33,7 +33,8 @@ require_once 'includes/markup.class.php'; // manipulate markup require_once 'includes/database.class.php'; // wrap DBSimple require_once 'includes/community.class.php'; // handle comments, screenshots and videos require_once 'includes/loot.class.php'; // build lv-tabs containing loot-information -require_once 'includes/smartAI.class.php'; +require_once 'includes/smartAI.class.php'; // TC: SmartAI system +require_once 'includes/conditions.class.php'; // TC: Conditions system require_once 'localization/lang.class.php'; require_once 'pages/genericPage.class.php'; diff --git a/includes/loot.class.php b/includes/loot.class.php index 4dad436d..9081798b 100644 --- a/includes/loot.class.php +++ b/includes/loot.class.php @@ -137,20 +137,21 @@ class Loot return array_combine($retKeys, $retData); } - private function getByContainerRecursive(string $tableName, int $lootId, array &$handledRefs, int $groupId = 0, float $baseChance = 1.0) : ?array + private function getByContainerRecursive(string $tableName, int $lootId, array &$handledRefs, int $groupId = 0, float $baseChance = 1.0) : array { $loot = []; $rawItems = []; if (!$tableName || !$lootId) - return null; + return [null, null]; $rows = DB::World()->select('SELECT * FROM ?# WHERE entry = ?d{ AND groupid = ?d}', $tableName, $lootId, $groupId ?: DBSIMPLE_SKIP); if (!$rows) - return null; + return [null, null]; $groupChances = []; $nGroupEquals = []; + $cnd = new Conditions(); foreach ($rows as $entry) { $set = array( @@ -161,6 +162,11 @@ class Loot 'groupChance' => 0 ); + if ($entry['QuestRequired']) + foreach (DB::Aowow()->selectCol('SELECT id FROM ?_quests WHERE (`reqSourceItemId1` = ?d OR `reqSourceItemId2` = ?d OR `reqSourceItemId3` = ?d OR `reqSourceItemId4` = ?d OR `reqItemId1` = ?d OR `reqItemId2` = ?d OR `reqItemId3` = ?d OR `reqItemId4` = ?d OR `reqItemId5` = ?d OR `reqItemId6` = ?d) AND (`cuFlags` & ?d) = 0', + $entry['Item'], $entry['Item'], $entry['Item'], $entry['Item'], $entry['Item'], $entry['Item'], $entry['Item'], $entry['Item'], $entry['Item'], $entry['Item'], CUSTOM_EXCLUDE_FOR_LISTVIEW | CUSTOM_UNAVAILABLE) as $questId) + $cnd->addExternalCondition(Conditions::lootTableToConditionSource($tableName), $lootId . ':' . $entry['Item'], [Conditions::QUESTTAKEN, $questId]); + // if ($entry['LootMode'] > 1) // { $buff = []; @@ -240,7 +246,8 @@ class Loot continue; } - $loot[] = $set; + $cndKey = $lootId . ':' . (-1 * ($set['reference'] ?? -$set['content'])); + $loot[$cndKey] = $set; } foreach (array_keys($nGroupEquals) as $k) @@ -257,6 +264,12 @@ class Loot $groupChances[$k] = (100 - $sum) / ($nGroupEquals[$k] ?: 1); } + if ($cnd->getBySourceGroup($lootId, Conditions::lootTableToConditionSource($tableName))) + { + self::storeJSGlobals($cnd->getJsGlobals()); + $cnd->toListviewColumn($loot, $this->extraCols); + } + return [$loot, array_unique($rawItems)]; } @@ -268,10 +281,6 @@ class Loot return false; /* - todo (high): implement conditions on loot (and conditions in general) - - also - // if (is_array($this->entry) && in_array($table, [LOOT_CREATURE, LOOT_GAMEOBJECT]) // iterate over the 4 available difficulties and assign modes @@ -279,16 +288,16 @@ class Loot modes:{"mode":1,"1":{"count":4408,"outof":16013},"4":{"count":4408,"outof":22531}} */ $handledRefs = []; - $struct = self::getByContainerRecursive($table, $this->entry, $handledRefs); - if (!$struct) + [$lootRows, $itemIds] = self::getByContainerRecursive($table, $this->entry, $handledRefs); + if (!$lootRows) return false; - $items = new ItemList(array(['i.id', $struct[1]], Cfg::get('SQL_LIMIT_NONE'))); - $this->jsGlobals = $items->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED); + $items = new ItemList(array(['i.id', $itemIds], Cfg::get('SQL_LIMIT_NONE'))); + self::storeJSGlobals($items->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); $foo = $items->getListviewData(); // assign listview LV rows to loot rows, not the other way round! The same item may be contained multiple times - foreach ($struct[0] as $loot) + foreach ($lootRows as $loot) { $base = array( 'percent' => round($loot['groupChance'] * $loot['realChanceMod'], 3), @@ -303,6 +312,9 @@ class Loot if ($_ = $loot['parentRef']) $base['reference'] = $_; + if (isset($loot['condition'])) + $base['condition'] = $loot['condition']; + if ($_ = self::createStack($loot)) $base['pctstack'] = $_; @@ -388,7 +400,7 @@ class Loot public function getByItem(int $entry, int $maxResults = -1, array $lootTableList = []) : bool { - $this->entry = intVal($entry); + $this->entry = $entry; if (!$this->entry) return false; @@ -445,6 +457,16 @@ class Loot $this->entry ); + /* i'm currently not seeing a reasonable way to blend this into creature/gobject/etc tabs as one entity may drop the same item multiple times, with and without conditions. + if ($newRefs) + { + $cnd = new Conditions(); + if ($cnd->getBySourceEntry($this->entry, Conditions::SRC_REFERENCE_LOOT_TEMPLATE)) + if ($cnd->toListviewColumn($newRefs, $x, $this->entry)) + self::storejsGlobals($cnd->getJsGlobals()); + } + */ + while ($newRefs) { $curRefs = $newRefs; @@ -460,14 +482,17 @@ class Loot /* search the real loot-templates for the itemId and gathered refds */ - for ($i = 1; $i < count($this->lootTemplates); $i++) + foreach ($this->lootTemplates as $lootTemplate) { - if ($lootTableList && !in_array($this->lootTemplates[$i], $lootTableList)) + if ($lootTableList && !in_array($lootTemplate, $lootTableList)) + continue; + + if ($lootTemplate == LOOT_REFERENCE) continue; $result = $this->calcChance(DB::World()->select( sprintf($query, '{lt1.reference IN (?a) OR }(lt1.reference = 0 AND lt1.item = ?d)'), - $this->lootTemplates[$i], $this->lootTemplates[$i], + $lootTemplate, $lootTemplate, $refResults ? array_keys($refResults) : DBSIMPLE_SKIP, $this->entry )); @@ -483,10 +508,10 @@ class Loot } // cap fetched entries to the sql-limit to guarantee, that the highest chance items get selected first - // screws with GO-loot and skinnig-loot as these templates are shared for several tabs (fish, herb, ore) (herb, ore, leather) + // screws with GO-loot and skinning-loot as these templates are shared for several tabs (fish, herb, ore) (herb, ore, leather) $ids = array_slice(array_keys($result), 0, $maxResults); - switch ($this->lootTemplates[$i]) + switch ($lootTemplate) { case LOOT_CREATURE: $field = 'lootId'; $tabId = 4; break; case LOOT_PICKPOCKET: $field = 'pickpocketLootId'; $tabId = 5; break; diff --git a/includes/types/item.class.php b/includes/types/item.class.php index 052991dd..9d2ee650 100644 --- a/includes/types/item.class.php +++ b/includes/types/item.class.php @@ -371,10 +371,8 @@ class ItemList extends BaseType $costArr['restock'] = $entries['restock']; if ($entries['event']) - { - $this->jsGlobals[Type::WORLDEVENT][$entries['event']] = $entries['event']; - $costArr['condition'][0][$this->id][] = [[CND_ACTIVE_EVENT, $entries['event']]]; - } + if (Conditions::extendListviewRow($costArr, Conditions::SRC_NONE, $this->id, [Conditions::ACTIVE_EVENT, $entries['event']])) + $this->jsGlobals[Type::WORLDEVENT][$entries['event']] = $entries['event']; if ($currency || $tokens) // fill idx:3 if required $costArr['cost'][] = $currency; diff --git a/includes/utilities.php b/includes/utilities.php index f09ad705..40e0a9ce 100644 --- a/includes/utilities.php +++ b/includes/utilities.php @@ -1179,149 +1179,6 @@ abstract class Util return DB::Aowow()->query('INSERT IGNORE INTO ?_account_reputation (?#) VALUES (?a)', array_keys($x), array_values($x)); } - public static function getServerConditions($srcType, $srcGroup = null, $srcEntry = null) - { - if (!$srcGroup && !$srcEntry) - return []; - - $result = []; - $jsGlobals = []; - - $conditions = DB::World()->select( - 'SELECT SourceTypeOrReferenceId, SourceEntry, SourceGroup, ElseGroup, - ConditionTypeOrReference, ConditionTarget, ConditionValue1, ConditionValue2, ConditionValue3, NegativeCondition - FROM conditions - WHERE SourceTypeOrReferenceId IN (?a) AND ?# = ?d - ORDER BY SourceTypeOrReferenceId, SourceEntry, SourceGroup, ElseGroup ASC', - is_array($srcType) ? $srcType : [$srcType], - $srcGroup ? 'SourceGroup' : 'SourceEntry', - $srcGroup ?: $srcEntry - ); - - foreach ($conditions as $c) - { - switch ($c['SourceTypeOrReferenceId']) - { - case CND_SRC_SPELL_CLICK_EVENT: // 18 - case CND_SRC_VEHICLE_SPELL: // 21 - case CND_SRC_NPC_VENDOR: // 23 - $jsGlobals[Type::NPC][] = $c['SourceGroup']; - break; - } - - switch ($c['ConditionTypeOrReference']) - { - case CND_AURA: // 1 - $c['ConditionValue2'] = null; // do not use his param - case CND_SPELL: // 25 - $jsGlobals[Type::SPELL][] = $c['ConditionValue1']; - break; - case CND_ITEM: // 2 - $c['ConditionValue3'] = null; // do not use his param - case CND_ITEM_EQUIPPED: // 3 - $jsGlobals[Type::ITEM][] = $c['ConditionValue1']; - break; - case CND_MAPID: // 22 - break down to area or remap for use with g_zone_categories - switch ($c['ConditionValue1']) - { - case 530: // outland - $c['ConditionValue1'] = 8; - break; - case 571: // northrend - $c['ConditionValue1'] = 10; - break; - case 0: // old world is fine - case 1: - break; - default: // remap for area - $cnd = array( - ['mapId', (int)$c['ConditionValue1']], - ['parentArea', 0], // not child zones - [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0], - 1 // only one result - ); - $zone = new ZoneList($cnd); - if (!$zone->error) - { - $jsGlobals[Type::ZONE][] = $zone->getField('id'); - $c['ConditionTypeOrReference'] = CND_ZONEID; - $c['ConditionValue1'] = $zone->getField('id'); - break; - } - else - continue 3; - } - case CND_ZONEID: // 4 - case CND_AREAID: // 23 - $jsGlobals[Type::ZONE][] = $c['ConditionValue1']; - break; - case CND_REPUTATION_RANK: // 5 - $jsGlobals[Type::FACTION][] = $c['ConditionValue1']; - break; - case CND_SKILL: // 7 - $jsGlobals[Type::SKILL][] = $c['ConditionValue1']; - break; - case CND_QUESTREWARDED: // 8 - case CND_QUESTTAKEN: // 9 - case CND_QUEST_NONE: // 14 - case CND_QUEST_COMPLETE: // 28 - $jsGlobals[Type::QUEST][] = $c['ConditionValue1']; - break; - case CND_ACTIVE_EVENT: // 12 - $jsGlobals[Type::WORLDEVENT][] = $c['ConditionValue1']; - break; - case CND_ACHIEVEMENT: // 17 - $jsGlobals[Type::ACHIEVEMENT][] = $c['ConditionValue1']; - break; - case CND_TITLE: // 18 - $jsGlobals[Type::TITLE][] = $c['ConditionValue1']; - break; - case CND_NEAR_CREATURE: // 29 - $jsGlobals[Type::NPC][] = $c['ConditionValue1']; - break; - case CND_NEAR_GAMEOBJECT: // 30 - $jsGlobals[Type::OBJECT][] = $c['ConditionValue1']; - break; - case CND_CLASS: // 15 - for ($i = 0; $i < 11; $i++) - if ($c['ConditionValue1'] & (1 << $i)) - $jsGlobals[Type::CHR_CLASS][] = $i + 1; - break; - case CND_RACE: // 16 - for ($i = 0; $i < 11; $i++) - if ($c['ConditionValue1'] & (1 << $i)) - $jsGlobals[Type::CHR_RACE][] = $i + 1; - break; - case CND_OBJECT_ENTRY: // 31 - if ($c['ConditionValue1'] == 3) - $jsGlobals[Type::NPC][] = $c['ConditionValue2']; - else if ($c['ConditionValue1'] == 5) - $jsGlobals[Type::OBJECT][] = $c['ConditionValue2']; - break; - case CND_TEAM: // 6 - if ($c['ConditionValue1'] == 469) // Alliance - $c['ConditionValue1'] = 1; - else if ($c['ConditionValue1'] == 67) // Horde - $c['ConditionValue1'] = 2; - else - continue 2; - } - - $res = [$c['NegativeCondition'] ? -$c['ConditionTypeOrReference'] : $c['ConditionTypeOrReference']]; - foreach ([1, 2, 3] as $i) - if (($_ = $c['ConditionValue'.$i]) || $c['ConditionTypeOrReference'] = CND_DISTANCE_TO) - $res[] = $_; - - $group = $c['SourceEntry']; - if (!in_array($c['SourceTypeOrReferenceId'], [CND_SRC_CREATURE_TEMPLATE_VEHICLE, CND_SRC_SPELL, CND_SRC_QUEST_ACCEPT, CND_SRC_QUEST_SHOW_MARK, CND_SRC_SPELL_PROC])) - $group = $c['SourceEntry'] . ':' . $c['SourceGroup']; - - $result[$c['SourceTypeOrReferenceId']] [$group] [$c['ElseGroup']] [] = $res; - } - - return [$result, $jsGlobals]; - } - public static function sendNoCacheHeader() { header('Expires: Sat, 01 Jan 2000 01:00:00 GMT'); diff --git a/pages/achievement.php b/pages/achievement.php index 38eb921f..bec23318 100644 --- a/pages/achievement.php +++ b/pages/achievement.php @@ -266,6 +266,15 @@ class AchievementPage extends GenericPage $this->extendGlobalData($coList->getJSGlobals()); } + // tab: condition for + $cnd = new Conditions(); + if ($cnd->getByCondition(Type::ACHIEVEMENT, $this->typeId)) + { + $this->extendGlobalData($cnd->getJsGlobals()); + $this->lvTabs[] = $cnd->toListviewTab('condition-for', '$LANG.tab_condition_for'); + } + + /*****************/ /* Criteria List */ /*****************/ diff --git a/pages/areatrigger.php b/pages/areatrigger.php index 4d867104..858ea42c 100644 --- a/pages/areatrigger.php +++ b/pages/areatrigger.php @@ -115,6 +115,15 @@ class AreaTriggerPage extends GenericPage /* Extra Tabs */ /**************/ + // tab: conditions + $cnd = new Conditions(); + $cnd->getBySourceEntry($this->typeId, Conditions::SRC_AREATRIGGER_CLIENT); + if ($tab = $cnd->toListviewTab()); + { + $this->extendGlobalData($cnd->getJsGlobals()); + $this->lvTabs[] = $tab; + } + if ($_type == AT_TYPE_OBJECTIVE) { $relQuest = new QuestList(array(['id', $this->subject->getField('quest')])); diff --git a/pages/currency.php b/pages/currency.php index ed05afd5..c318001c 100644 --- a/pages/currency.php +++ b/pages/currency.php @@ -118,9 +118,7 @@ class CurrencyPage extends GenericPage if (!$soldBy->error) { $sbData = $soldBy->getListviewData(); - $extraCols = ['$Listview.extraCols.stock', "\$Listview.funcBox.createSimpleCol('stack', 'stack', '10%', 'stack')", '$Listview.extraCols.cost']; - $holidays = []; - + $extraCols = ['$Listview.extraCols.stock', "\$Listview.funcBox.createSimpleCol('stack', 'stack', '10%', 'stack')", '$Listview.extraCols.cost', '$Listview.extraCols.condition']; foreach ($sbData as $k => &$row) { $items = []; @@ -137,14 +135,9 @@ class CurrencyPage extends GenericPage $items[] = [-$id, $qty]; } - if ($vendors[$k][0]['event']) - { - if (count($extraCols) == 3) // not already pushed - $extraCols[] = '$Listview.extraCols.condition'; - - $this->extendGlobalIds(Type::WORLDEVENT, $vendors[$k][0]['event']); - $row['condition'][0][$this->typeId][] = [[CND_ACTIVE_EVENT, $vendors[$k][0]['event']]]; - } + if ($e = $vendors[$k][0]['event']) + if (Conditions::extendListviewRow($row, Conditions::SRC_NONE, $k, [Conditions::ACTIVE_EVENT, $e])) + $this->extendGlobalIds(Type::WORLDEVENT, $e); $row['stock'] = $vendors[$k][0]['stock']; $row['stack'] = $itemObj->getField('buyCount'); @@ -155,6 +148,10 @@ class CurrencyPage extends GenericPage ); } + // no conditions > remove conditions column + if (!array_column($sbData, 'condition')) + array_pop($extraCols); + $this->lvTabs[] = [CreatureList::$brickFile, array( 'data' => array_values($sbData), 'name' => '$LANG.tab_soldby', diff --git a/pages/event.php b/pages/event.php index c9e3ceb5..00bf12f9 100644 --- a/pages/event.php +++ b/pages/event.php @@ -244,21 +244,16 @@ class EventPage extends GenericPage $this->extendGlobalData($relEvents->getJSGlobals()); $relData = $relEvents->getListviewData(); foreach ($relEvents->getFoundIDs() as $id) - $relData[$id]['condition'][0][$this->typeId][] = [[-CND_ACTIVE_EVENT, $this->eId]]; + Conditions::extendListviewRow($relData[$id], Conditions::SRC_NONE, $this->typeId, [-Conditions::ACTIVE_EVENT, $this->eId]); $this->extendGlobalData($this->subject->getJSGlobals()); + $d = $this->subject->getListviewData(); foreach ($rel as $r) - { - if ($r <= 0) - continue; + if ($r > 0) + if (Conditions::extendListviewRow($d[$this->eId], Conditions::SRC_NONE, $this->typeId, [-Conditions::ACTIVE_EVENT, $r])) + $this->extendGlobalIds(Type::WORLDEVENT, $r); - $this->extendGlobalIds(Type::WORLDEVENT, $r); - - $d = $this->subject->getListviewData(); - $d[$this->eId]['condition'][0][$this->typeId][] = [[-CND_ACTIVE_EVENT, $r]]; - - $relData = array_merge($relData, $d); - } + $relData = array_merge($relData, $d); $this->lvTabs[] = [WorldEventList::$brickFile, array( 'data' => array_values($relData), @@ -269,6 +264,14 @@ class EventPage extends GenericPage )]; } } + + // tab: condition for + $cnd = new Conditions(); + if ($cnd->getByCondition(Type::WORLDEVENT, $this->typeId)) + { + $this->extendGlobalData($cnd->getJsGlobals()); + $this->lvTabs[] = $cnd->toListviewTab('condition-for', '$LANG.tab_condition_for'); + } } protected function generateTooltip() : string @@ -343,7 +346,6 @@ class EventPage extends GenericPage $data['endDate'] = $updated['end'] ? date(Util::$dateFormatInternal, $updated['end']) : false; $data['rec'] = $updated['rec']; } - } } } diff --git a/pages/item.php b/pages/item.php index 3f5a45c2..5ffa1a12 100644 --- a/pages/item.php +++ b/pages/item.php @@ -443,8 +443,8 @@ class ItemPage extends genericPage foreach ($lvData as $sId => &$data) { $data['percent'] = $perfItem[$sId]['perfectCreateChance']; - $data['condition'][0][$this->typeId] = [[[CND_SPELL, $perfItem[$sId]['requiredSpecialization']]]]; - $this->extendGlobalIDs(Type::SPELL, $perfItem[$sId]['requiredSpecialization']); + if (Conditions::extendListviewRow($data, Conditions::SRC_NONE, $this->typeId, [Conditions::SPELL, $perfItem[$sId]['requiredSpecialization']])) + $this->extendGlobalIDs(Type::SPELL, $perfItem[$sId]['requiredSpecialization']); } $this->lvTabs[] = [SpellList::$brickFile, array( @@ -471,7 +471,6 @@ class ItemPage extends genericPage if ($idx == 16) $createdBy = array_column($tabData['data'], 'id'); - $s = $sm = null; if ($idx == 4 && $this->subject->getSources($s, $sm) && $s[0] == SRC_DROP && isset($sm[0]['dd'])) { switch ($sm[0]['dd']) @@ -492,76 +491,36 @@ class ItemPage extends genericPage // tabs: this item contains.. $sourceFor = array( - [LOOT_ITEM, $this->subject->id, '$LANG.tab_contains', 'contains', ['$Listview.extraCols.percent'], [] , []], - [LOOT_PROSPECTING, $this->subject->id, '$LANG.tab_prospecting', 'prospecting', ['$Listview.extraCols.percent'], ['side', 'slot', 'reqlevel'], []], - [LOOT_MILLING, $this->subject->id, '$LANG.tab_milling', 'milling', ['$Listview.extraCols.percent'], ['side', 'slot', 'reqlevel'], []], - [LOOT_DISENCHANT, $this->subject->getField('disenchantId'), '$LANG.tab_disenchanting', 'disenchanting', ['$Listview.extraCols.percent'], ['side', 'slot', 'reqlevel'], []] + [LOOT_ITEM, $this->subject->id, '$LANG.tab_contains', 'contains', ['$Listview.extraCols.percent'], [] ], + [LOOT_PROSPECTING, $this->subject->id, '$LANG.tab_prospecting', 'prospecting', ['$Listview.extraCols.percent'], ['side', 'slot', 'reqlevel']], + [LOOT_MILLING, $this->subject->id, '$LANG.tab_milling', 'milling', ['$Listview.extraCols.percent'], ['side', 'slot', 'reqlevel']], + [LOOT_DISENCHANT, $this->subject->getField('disenchantId'), '$LANG.tab_disenchanting', 'disenchanting', ['$Listview.extraCols.percent'], ['side', 'slot', 'reqlevel']] ); - $reqQuest = []; - foreach ($sourceFor as $sf) + foreach ($sourceFor as [$lootTemplate, $lootId, $tabName, $tabId, $extraCols, $hiddenCols]) { $lootTab = new Loot(); - if ($lootTab->getByContainer($sf[0], $sf[1])) + if ($lootTab->getByContainer($lootTemplate, $lootId)) { $this->extendGlobalData($lootTab->jsGlobals); - $sf[4] = array_merge($sf[4], $lootTab->extraCols); - - foreach ($lootTab->iterate() as $lv) - { - if (!$lv['quest']) - continue; - - $sf[4] = array_merge($sf[4], ['$Listview.extraCols.condition']); - - $reqQuest[$lv['id']] = 0; - - $lv['condition'][0][$this->typeId][] = [[CND_QUESTTAKEN, &$reqQuest[$lv['id']]]]; - } + $extraCols = array_merge($extraCols, $lootTab->extraCols); $tabData = array( 'data' => array_values($lootTab->getResult()), - 'name' => $sf[2], - 'id' => $sf[3], + 'name' => $tabName, + 'id' => $tabId, ); - if ($sf[4]) - $tabData['extraCols'] = array_unique($sf[4]); + if ($extraCols) + $tabData['extraCols'] = array_unique($extraCols); - if ($sf[5]) - $tabData['hiddenCols'] = array_unique($sf[5]); - - if ($sf[6]) - $tabData['visibleCols'] = array_unique($sf[6]); + if ($hiddenCols) + $tabData['hiddenCols'] = array_unique($hiddenCols); $this->lvTabs[] = [ItemList::$brickFile, $tabData]; } } - if ($reqIds = array_keys($reqQuest)) // apply quest-conditions as back-reference - { - $conditions = array( - 'OR', - ['reqSourceItemId1', $reqIds], ['reqSourceItemId2', $reqIds], - ['reqSourceItemId3', $reqIds], ['reqSourceItemId4', $reqIds], - ['reqItemId1', $reqIds], ['reqItemId2', $reqIds], ['reqItemId3', $reqIds], - ['reqItemId4', $reqIds], ['reqItemId5', $reqIds], ['reqItemId6', $reqIds] - ); - - $reqQuests = new QuestList($conditions); - $reqQuests->getJSGlobals(GLOBALINFO_SELF); - - foreach ($reqQuests->iterate() as $qId => $__) - { - if (empty($reqQuests->requires[$qId][Type::ITEM])) - continue; - - foreach ($reqIds as $rId) - if (in_array($rId, $reqQuests->requires[$qId][Type::ITEM])) - $reqQuest[$rId] = $reqQuests->id; - } - } - // tab: container can contain if ($this->subject->getField('slots') > 0) { @@ -795,7 +754,7 @@ class ItemPage extends genericPage $extraCols = ['$Listview.extraCols.stock', "\$Listview.funcBox.createSimpleCol('stack', 'stack', '10%', 'stack')", '$Listview.extraCols.cost']; - $holidays = []; + $cnd = new Conditions(); foreach ($sbData as $k => &$row) { $currency = []; @@ -817,13 +776,7 @@ class ItemPage extends genericPage $row['cost'] = [empty($vendors[$k][0][0]) ? 0 : $vendors[$k][0][0]]; if ($e = $vendors[$k][0]['event']) - { - if (count($extraCols) == 3) - $extraCols[] = '$Listview.extraCols.condition'; - - $this->extendGlobalIds(Type::WORLDEVENT, $e); - $row['condition'][0][$this->typeId][] = [[CND_ACTIVE_EVENT, $e]]; - } + $cnd->addExternalCondition(Conditions::SRC_NONE, $k, [Conditions::ACTIVE_EVENT, $e]); if ($currency || $tokens) // fill idx:3 if required $row['cost'][] = $currency; @@ -841,6 +794,8 @@ class ItemPage extends genericPage $row['stack'] = $x; } + if ($cnd->toListviewColumn($sbData, $extraCols)) + $this->extendGlobalData($cnd->getJsGlobals()); $this->lvTabs[] = [CreatureList::$brickFile, array( 'data' => array_values($sbData), @@ -1102,11 +1057,11 @@ class ItemPage extends genericPage } // itemsource - if ($this->subject->getSources($s, $m)) + if ($this->subject->getSources($s, $sm)) { $json['source'] = $s; - if ($m) - $json['sourcemore'] = $m; + if ($sm) + $json['sourcemore'] = $sm; } $xml->addChild('json')->addCData(substr(json_encode($json), 1, -1)); diff --git a/pages/npc.php b/pages/npc.php index cd9b5694..d2f8dd76 100644 --- a/pages/npc.php +++ b/pages/npc.php @@ -572,40 +572,25 @@ class NpcPage extends GenericPage $this->extendGlobalData($teaches->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); $data = $teaches->getListviewData(); - $extra = []; + $extraCols = []; + $cnd = new Conditions(); foreach ($tSpells as $sId => $train) { if (empty($data[$sId])) continue; if ($_ = $train['reqSkillId']) - { if (count($data[$sId]['skill']) == 1 && $_ != $data[$sId]['skill'][0]) - { - $this->extendGlobalIds(Type::SKILL, $_); - if (!isset($extra[0])) - $extra[0] = '$Listview.extraCols.condition'; - - $data[$sId]['condition'][0][$this->typeId][] = [[CND_SKILL, $_, $train['reqSkillValue']]]; - } - } + $cnd->addExternalCondition(Conditions::SRC_NONE, $sId, [Conditions::SKILL, $_, $train['reqSkillValue']]); for ($i = 1; $i < 3; $i++) - { if ($_ = $train['reqSpellId'.$i]) - { - $this->extendGlobalIds(Type::SPELL, $_); - if (!isset($extra[0])) - $extra[0] = '$Listview.extraCols.condition'; - - $data[$sId]['condition'][0][$this->typeId][] = [[CND_SPELL, $_]]; - } - } + $cnd->addExternalCondition(Conditions::SRC_NONE, $sId, [Conditions::SPELL, $_]); if ($_ = $train['reqLevel']) { - if (!isset($extra[1])) - $extra[1] = "\$Listview.funcBox.createSimpleCol('reqLevel', LANG.tooltip_reqlevel, '7%', 'reqLevel')"; + if (!isset($extraCols[1])) + $extraCols[1] = "\$Listview.funcBox.createSimpleCol('reqLevel', LANG.tooltip_reqlevel, '7%', 'reqLevel')"; $data[$sId]['reqLevel'] = $_; } @@ -614,6 +599,9 @@ class NpcPage extends GenericPage $data[$sId]['trainingcost'] = $_; } + if ($cnd->toListviewColumn($data, $extraCols)) + $this->extendGlobalData($cnd->getJsGlobals()); + $tabData = array( 'data' => array_values($data), 'name' => '$LANG.tab_teaches', @@ -621,8 +609,8 @@ class NpcPage extends GenericPage 'visibleCols' => ['trainingcost'] ); - if ($extra) - $tabData['extraCols'] = array_values($extra); + if ($extraCols) + $tabData['extraCols'] = array_values($extraCols); $this->lvTabs[] = [SpellList::$brickFile, $tabData]; } @@ -639,28 +627,23 @@ class NpcPage extends GenericPage { $colAddIn = null; $extraCols = ["\$Listview.funcBox.createSimpleCol('stack', 'stack', '10%', 'stack')", '$Listview.extraCols.cost']; - if ($soldItems->hasSetFields('condition')) - $extraCols[] = '$Listview.extraCols.condition'; $lvData = $soldItems->getListviewData(ITEMINFO_VENDOR, [Type::NPC => [$this->typeId]]); + if (array_column($lvData, 'condition')) + $extraCols[] = '$Listview.extraCols.condition'; + if (array_filter(array_column($lvData, 'restock'))) { $extraCols[] = '$_'; $colAddIn = 'vendorRestockCol'; } - $sc = Util::getServerConditions(CND_SRC_NPC_VENDOR, $this->typeId); - if (!empty($sc[0])) + $cnd = new Conditions(); + if ($cnd->getBySourceGroup($this->typeId, Conditions::SRC_NPC_VENDOR)) { - $this->extendGlobalData($sc[1]); - - $extraCols[] = '$Listview.extraCols.condition'; - - foreach ($lvData as $id => &$row) - foreach ($sc[0] as $srcType => $cndData) - if (!empty($cndData[$id.':'.$this->typeId])) - $row['condition'][0][$id.':'.$this->typeId] = $cndData[$id.':'.$this->typeId]; + $this->extendGlobalData($cnd->getJsGlobals()); + $cnd->toListviewColumn($lvData, $extraCols); } $this->lvTabs[] = [ItemList::$brickFile, array( @@ -725,65 +708,36 @@ class NpcPage extends GenericPage foreach ($lootGOs as $idx => $lgo) array_splice($sourceFor, 1, 0, [[LOOT_GAMEOBJECT, $lgo['lootId'], $mapType ? $langref[($mapType == 1 ? -1 : 1) + ($lgo['modeDummy'] ? 1 : 0)] : '$LANG.tab_drops', 'drops-object-'.$idx, [], 'note' => '$$WH.sprintf(LANG.lvnote_npcobjectsource, '.$lgo['id'].', "'.Util::localizedString($lgo, 'name').'")']]); - $lootGOs = DB::World()->select('select SourceEntry, ConditionValue1, ConditionValue2 from conditions where SourceTypeOrReferenceId = 1 and SourceGroup = ?d and ConditionTypeOrReference = ?d', $this->typeId, CND_SKILL); - - $reqQuest = []; - foreach ($sourceFor as $sf) + foreach ($sourceFor as [$lootTpl, $lootId, $tabName, $tabId, $hiddenCols]) { $creatureLoot = new Loot(); - if ($creatureLoot->getByContainer($sf[0], $sf[1])) + if ($creatureLoot->getByContainer($lootTpl, $lootId)) { $extraCols = $creatureLoot->extraCols; $extraCols[] = '$Listview.extraCols.percent'; $this->extendGlobalData($creatureLoot->jsGlobals); - $this->extendWithConditions($creatureLoot, $lootGOs, $extraCols, $reqQuest); - $tabData = array( 'data' => array_values($creatureLoot->getResult()), - 'name' => $sf[2], - 'id' => $sf[3], - 'extraCols' => $extraCols, + 'name' => $tabName, + 'id' => $tabId, + 'extraCols' => array_values(array_unique($extraCols)), 'sort' => ['-percent', 'name'] ); if (!empty($sf['note'])) $tabData['note'] = $sf['note']; - else if ($sf[0] == LOOT_SKINNING) + else if ($lootTpl == LOOT_SKINNING) $tabData['note'] = ''.Lang::formatSkillBreakpoints(Game::getBreakpointsForSkill($skinTab[2], $this->subject->getField('maxLevel')), Lang::FMT_HTML).''; - if ($sf[4]) - $tabData['hiddenCols'] = $sf[4]; + if ($hiddenCols) + $tabData['hiddenCols'] = $hiddenCols; $this->lvTabs[] = [ItemList::$brickFile, $tabData]; } } - if ($reqIds = array_keys($reqQuest)) // apply quest-conditions as back-reference - { - $conditions = array( - 'OR', - ['reqSourceItemId1', $reqIds], ['reqSourceItemId2', $reqIds], - ['reqSourceItemId3', $reqIds], ['reqSourceItemId4', $reqIds], - ['reqItemId1', $reqIds], ['reqItemId2', $reqIds], ['reqItemId3', $reqIds], - ['reqItemId4', $reqIds], ['reqItemId5', $reqIds], ['reqItemId6', $reqIds] - ); - - $reqQuests = new QuestList($conditions); - $this->extendGlobalData($reqQuests->getJSGlobals()); - - foreach ($reqQuests->iterate() as $qId => $__) - { - if (empty($reqQuests->requires[$qId][Type::ITEM])) - continue; - - foreach ($reqIds as $rId) - if (in_array($rId, $reqQuests->requires[$qId][Type::ITEM])) - $reqQuest[$rId] = $reqQuests->id; - } - } - // tab: starts quest // tab: ends quest $startEnd = new QuestList(array(['qse.type', Type::NPC], ['qse.typeId', $this->typeId])); @@ -914,6 +868,14 @@ class NpcPage extends GenericPage $this->lvTabs[] = [SoundList::$brickFile, $tabData]; } } + + // tab: conditions + $cnd = new Conditions(); + if ($cnd->getBySourceEntry($this->typeId, Conditions::SRC_CREATURE_TEMPLATE_VEHICLE)) + { + $this->extendGlobalData($cnd->getJsGlobals()); + $this->lvTabs[] = $cnd->toListviewTab(); + } } protected function generateTooltip() @@ -1045,49 +1007,6 @@ class NpcPage extends GenericPage return [$quotes, $nQuotes]; } - - private function getConditions($itemId, $data) - { - foreach ($data as $datum) - { - if ($datum['SourceEntry'] == $itemId) - { - return [CND_SKILL, $datum['ConditionValue1'], $datum['ConditionValue2']]; - } - } - - return null; - } - - private function extendWithConditions($creatureLoot, $lootConditions, &$extraCols, &$reqQuest) - { - $hasExtraCol = false; - $reqSkill = []; - - foreach ($creatureLoot->iterate() as &$lv) - { - if ($lv['quest']) - { - $hasExtraCol = true; - $reqQuest[$lv['id']] = 0; - $lv['condition'][0][$this->typeId][] = [[CND_QUESTTAKEN, &$reqQuest[$lv['id']]]]; - } - elseif ($skill = $this->getConditions($lv['id'], $lootConditions)) - { - $hasExtraCol = true; - $lv['condition'][0][$this->typeId][] = [$skill]; - $reqSkill[] = $skill[1]; - } - } - - if ($hasExtraCol) - { - $extraCols[] = '$Listview.extraCols.condition'; - } - - $reqSkills = new SkillList(['OR', ['id', array_unique($reqSkill)]]); - $this->extendGlobalData($reqSkills->getJSGlobals()); - } } diff --git a/pages/object.php b/pages/object.php index c08437cf..9cb68f1b 100644 --- a/pages/object.php +++ b/pages/object.php @@ -230,7 +230,7 @@ class ObjectPage extends GenericPage $relBoss = null; - if ($ll = DB::Aowow()->selectRow('SELECT * FROM ?_loot_link WHERE objectId = ?d ORDER BY priority DESC LIMIT 1', $this->typeId)) + if ($ll = DB::Aowow()->selectRow('SELECT * FROM ?_loot_link WHERE `objectId` = ?d ORDER BY `priority` DESC LIMIT 1', $this->typeId)) { // group encounter if ($ll['encounterId']) @@ -386,7 +386,6 @@ class ObjectPage extends GenericPage } // tab: contains - $reqQuest = []; if ($_ = $this->subject->getField('lootId')) { $goLoot = new Loot(); @@ -397,24 +396,18 @@ class ObjectPage extends GenericPage $hiddenCols = ['source', 'side', 'slot', 'reqlevel']; $this->extendGlobalData($goLoot->jsGlobals); + $lootResult = $goLoot->getResult(); - foreach ($goLoot->iterate() as &$lv) + foreach ($hiddenCols as $k => $str) { - if (!empty($hiddenCols)) - foreach ($hiddenCols as $k => $str) - if (!empty($lv[$str])) - unset($hiddenCols[$k]); - - if (!$lv['quest']) - continue; - - $extraCols[] = '$Listview.extraCols.condition'; - $reqQuest[$lv['id']] = 0; - $lv['condition'][0][$this->typeId][] = [[CND_QUESTTAKEN, &$reqQuest[$lv['id']]]]; + if ($k == 1 && array_filter(array_column($lootResult, $str), function ($x) { return $x != SIDE_BOTH; })) + unset($hiddenCols[$k]); + else if ($k != 1 && array_column($lootResult, $str)) + unset($hiddenCols[$k]); } $tabData = array( - 'data' => array_values($goLoot->getResult()), + 'data' => array_values($lootResult), 'id' => 'contains', 'name' => '$LANG.tab_contains', 'sort' => ['-percent', 'name'], @@ -422,36 +415,12 @@ class ObjectPage extends GenericPage ); if ($hiddenCols) - $tabData['hiddenCols'] = $hiddenCols; + $tabData['hiddenCols'] = array_values($hiddenCols); $this->lvTabs[] = [ItemList::$brickFile, $tabData]; } } - if ($reqIds = array_keys($reqQuest)) // apply quest-conditions as back-reference - { - $conditions = array( - 'OR', - ['reqSourceItemId1', $reqIds], ['reqSourceItemId2', $reqIds], - ['reqSourceItemId3', $reqIds], ['reqSourceItemId4', $reqIds], - ['reqItemId1', $reqIds], ['reqItemId2', $reqIds], ['reqItemId3', $reqIds], - ['reqItemId4', $reqIds], ['reqItemId5', $reqIds], ['reqItemId6', $reqIds] - ); - - $reqQuests = new QuestList($conditions); - $this->extendGlobalData($reqQuests->getJSGlobals()); - - foreach ($reqQuests->iterate() as $qId => $__) - { - if (empty($reqQuests->requires[$qId][Type::ITEM])) - continue; - - foreach ($reqIds as $rId) - if (in_array($rId, $reqQuests->requires[$qId][Type::ITEM])) - $reqQuest[$rId] = $reqQuests->id; - } - } - // tab: Spell Focus for if ($sfId = $this->subject->getField('spellFocusId')) { diff --git a/pages/quest.php b/pages/quest.php index 977dea71..b5ab344e 100644 --- a/pages/quest.php +++ b/pages/quest.php @@ -1012,49 +1012,19 @@ class QuestPage extends GenericPage } // tab: conditions - $cnd = []; + $cnd = new Conditions(); + $cnd->getBySourceEntry($this->typeId, Conditions::SRC_QUEST_AVAILABLE, Conditions::SRC_QUEST_SHOW_MARK); + if ($_ = $this->subject->getField('reqMinRepFaction')) - { - $cnd[CND_SRC_QUEST_ACCEPT][$this->typeId][0][] = [CND_REPUTATION_RANK, $_, 1 << Game::getReputationLevelForPoints($this->subject->getField('reqMinRepValue'))]; - $this->extendGlobalIds(Type::FACTION, $_); - } + $cnd->addExternalCondition(Conditions::SRC_QUEST_AVAILABLE, $this->typeId, [Conditions::REPUTATION_RANK, $_, 1 << Game::getReputationLevelForPoints($this->subject->getField('reqMinRepValue'))]); if ($_ = $this->subject->getField('reqMaxRepFaction')) + $cnd->addExternalCondition(Conditions::SRC_QUEST_AVAILABLE, $this->typeId, [-Conditions::REPUTATION_RANK, $_, 1 << Game::getReputationLevelForPoints($this->subject->getField('reqMaxRepValue'))]); + + if ($tab = $cnd->toListviewTab()) { - $cnd[CND_SRC_QUEST_ACCEPT][$this->typeId][0][] = [-CND_REPUTATION_RANK, $_, 1 << Game::getReputationLevelForPoints($this->subject->getField('reqMaxRepValue'))]; - $this->extendGlobalIds(Type::FACTION, $_); - } - - $_ = Util::getServerConditions([CND_SRC_QUEST_ACCEPT, CND_SRC_QUEST_SHOW_MARK], null, $this->typeId); - if (!empty($_[0])) - { - // awkward merger - if (isset($_[0][CND_SRC_QUEST_ACCEPT][$this->typeId][0])) - { - if (isset($cnd[CND_SRC_QUEST_ACCEPT][$this->typeId][0])) - $cnd[CND_SRC_QUEST_ACCEPT][$this->typeId][0] = array_merge($cnd[CND_SRC_QUEST_ACCEPT][$this->typeId][0], $_[0][CND_SRC_QUEST_ACCEPT][$this->typeId][0]); - else - $cnd[CND_SRC_QUEST_ACCEPT] = $_[0][CND_SRC_QUEST_ACCEPT]; - } - - if (isset($_[0][CND_SRC_QUEST_SHOW_MARK])) - $cnd[CND_SRC_QUEST_SHOW_MARK] = $_[0][CND_SRC_QUEST_SHOW_MARK]; - - $this->extendGlobalData($_[1]); - } - - if ($cnd) - { - $tab = ""; - - $this->lvTabs[] = [null, array( - 'data' => $tab, - 'id' => 'conditions', - 'name' => '$LANG.requires' - )]; + $this->extendGlobalData($cnd->getJsGlobals()); + $this->lvTabs[] = $tab; } } diff --git a/pages/sound.php b/pages/sound.php index 2c1dcbed..9c0ddd05 100644 --- a/pages/sound.php +++ b/pages/sound.php @@ -249,7 +249,7 @@ class SoundPage extends GenericPage foreach ($zoneIds as $zData) if ($zData['worldStateId']) - $zoneData[$zData['id']]['condition'][0][$this->typeId][] = [[CND_WORLD_STATE, $zData['worldStateId'], $zData['worldStateValue']]]; + Conditions::extendListviewRow($zoneData[$zData['id']], Conditions::SRC_NONE, $this->typeId, [Conditions::WORLD_STATE, $zData['worldStateId'], $zData['worldStateValue']]); } $tabData['data'] = array_values($zoneData); diff --git a/pages/spell.php b/pages/spell.php index 78607b0a..5f61ec5f 100644 --- a/pages/spell.php +++ b/pages/spell.php @@ -746,12 +746,15 @@ class SpellPage extends GenericPage $lv[$bar] = $foo[$bar]; $lv[$bar]['percent'] = $extraItem['additionalCreateChance']; $lv[$bar]['pctstack'] = $this->buildPctStack($extraItem['additionalCreateChance'] / 100, $extraItem['additionalMaxNum']); - $lv[$bar]['condition'][0][$this->typeId][] = [[CND_SPELL, $extraItem['requiredSpecialization']]]; - $this->extendGlobalIds(Type::SPELL, $extraItem['requiredSpecialization']); - $extraCols[] = '$Listview.extraCols.condition'; if ($max = ($extraItem['additionalMaxNum'] - 1)) $lv[$bar]['stack'] = [1, $max]; + if (Conditions::extendListviewRow($lv[$bar], Conditions::SRC_NONE, $this->typeId, [Conditions::SPELL, $extraItem['requiredSpecialization']])) + { + $this->extendGlobalIds(Type::SPELL, $extraItem['requiredSpecialization']); + $extraCols[] = '$Listview.extraCols.condition'; + } + break; // skill_extra_item_template can only contain 1 item } } @@ -926,119 +929,46 @@ class SpellPage extends GenericPage } // tab: zone - if ($areas = DB::World()->select('SELECT * FROM spell_area WHERE spell = ?d', $this->typeId)) + if ($areaSpells = DB::World()->select('SELECT `area` AS ARRAY_KEY, `aura_spell` AS "0", `quest_start` AS "1", `quest_end` AS "2", `quest_start_status` AS "3", `quest_end_status` AS "4", `racemask` AS "5", `gender` AS "6" FROM spell_area WHERE spell = ?d', $this->typeId)) { - $zones = new ZoneList(array(['id', array_column($areas, 'area')])); + $zones = new ZoneList(array(['id', array_keys($areaSpells)])); if (!$zones->error) { $lvZones = $zones->getListviewData(); $this->extendGlobalData($zones->getJSGlobals()); - $lv = []; - $parents = []; - $extra = false; - foreach ($areas as $a) + $resultLv = []; + $parents = []; + foreach ($areaSpells as $areaId => $condition) { - if (empty($lvZones[$a['area']])) + if (empty($lvZones[$areaId])) continue; - $condition = []; - if ($a['aura_spell']) - { - $this->extendGlobalIds(Type::SPELL, abs($a['aura_spell'])); - $condition[0][$this->typeId][] = [[$a['aura_spell'] > 0 ? CND_AURA : -CND_AURA, abs($a['aura_spell'])]]; - } + $row = $lvZones[$areaId]; - if ($a['quest_start']) // status for quests needs work - { - $this->extendGlobalIds(Type::QUEST, $a['quest_start']); - $group = []; - for ($i = 0; $i < 7; $i++) - { - if (!($a['quest_start_status'] & (1 << $i))) - continue; + // attach to lv row and evaluate after merging + $row['__condition'] = $condition; - if ($i == 0) - $group[] = [CND_QUEST_NONE, $a['quest_start']]; - else if ($i == 1) - $group[] = [CND_QUEST_COMPLETE, $a['quest_start']]; - else if ($i == 3) - $group[] = [CND_QUESTTAKEN, $a['quest_start']]; - else if ($i == 6) - $group[] = [CND_QUESTREWARDED, $a['quest_start']]; - } - - if ($group) - $condition[0][$this->typeId][] = $group; - } - - if ($a['quest_end'] && $a['quest_end'] != $a['quest_start']) - { - $this->extendGlobalIds(Type::QUEST, $a['quest_end']); - $group = []; - for ($i = 0; $i < 7; $i++) - { - if (!($a['quest_end_status'] & (1 << $i))) - continue; - - if ($i == 0) - $group[] = [-CND_QUEST_NONE, $a['quest_end']]; - else if ($i == 1) - $group[] = [-CND_QUEST_COMPLETE, $a['quest_end']]; - else if ($i == 3) - $group[] = [-CND_QUESTTAKEN, $a['quest_end']]; - else if ($i == 6) - $group[] = [-CND_QUESTREWARDED, $a['quest_end']]; - } - - if ($group) - $condition[0][$this->typeId][] = $group; - } - - if ($a['racemask']) - { - $foo = []; - for ($i = 0; $i < 11; $i++) - if ($a['racemask'] & (1 << $i)) - $foo[] = $i + 1; - - $this->extendGlobalIds(Type::CHR_RACE, ...$foo); - $condition[0][$this->typeId][] = [[CND_RACE, $a['racemask']]]; - } - - if ($a['gender'] != 2) // 2: both - $condition[0][$this->typeId][] = [[CND_GENDER, $a['gender'] + 1]]; - - $row = $lvZones[$a['area']]; - if ($condition) - { - $extra = true; - $row = array_merge($row, ['condition' => $condition]); - } - - // merge subzones, into one row, if: conditions match && parentZone is shared - if ($p = $zones->getEntry($a['area'])['parentArea']) + // merge subzones, into one row, if: spell_area data is identical && parentZone is shared + if ($p = $zones->getEntry($areaId)['parentArea']) { $parents[] = $p; - $row['parentArea'] = $p; - $row['subzones'] = [$a['area']]; + $row['__parent'] = $p; + $row['subzones'] = [$areaId]; } else - $row['parentArea'] = 0; + $row['__parent'] = 0; $set = false; - foreach ($lv as &$v) + foreach ($resultLv as &$v) { - if ($v['parentArea'] != $row['parentArea'] && $v['id'] != $row['parentArea']) + if ($v['__parent'] != $row['__parent'] && $v['id'] != $row['__parent']) continue; - if (empty($v['condition']) xor empty($row['condition'])) + if ($v['__condition'] != $row['__condition']) continue; - if (!empty($row['condition']) && !empty($v['condition']) && $v['condition'] != $row['condition']) - continue; - - if (!$row['parentArea'] && $v['id'] != $row['parentArea']) + if (!$row['__parent'] && $v['id'] != $row['__parent']) continue; $set = true; @@ -1050,7 +980,7 @@ class SpellPage extends GenericPage if (!$set) { $row['subzones'] = [$row['id']]; - $lv[] = $row; + $resultLv[] = $row; } } @@ -1058,16 +988,44 @@ class SpellPage extends GenericPage if ($parents) { $parents = (new ZoneList(array(['id', $parents])))->getListviewData(); - foreach ($lv as &$_) - if (isset($parents[$_['parentArea']])) - $_ = array_merge($_, $parents[$_['parentArea']]); + foreach ($resultLv as &$_) + if (isset($parents[$_['__parent']])) + $_ = array_merge($_, $parents[$_['__parent']]); } - $tabData = ['data' => array_values($lv)]; - - if ($extra) + $cnd = new Conditions(); + foreach ($resultLv as $idx => $lv) { - $tabData['extraCols'] = ['$Listview.extraCols.condition']; + [$auraSpell, $questStart, $questEnd, $questStartState, $questEndState, $raceMask, $gender] = $lv['__condition']; + + if ($auraSpell) + $cnd->addExternalCondition(Conditions::SRC_NONE, $lv['id'], [$auraSpell > 0 ? Conditions::AURA : -Conditions::AURA, abs($auraSpell)]); + + if ($questStart) + $cnd->addExternalCondition(Conditions::SRC_NONE, $lv['id'], [Conditions::QUESTSTATE, $questStart, $questStartState]); + + if ($questEnd && $questEnd != $questStart) + $cnd->addExternalCondition(Conditions::SRC_NONE, $lv['id'], [-Conditions::QUESTSTATE, $questEnd, $questEndState]); + + if ($raceMask) + $cnd->addExternalCondition(Conditions::SRC_NONE, $lv['id'], [-Conditions::CHR_RACE, $raceMask]); + + if ($gender != 2) // 2: both + $cnd->addExternalCondition(Conditions::SRC_NONE, $lv['id'], [-Conditions::GENDER, $gender + 1]); + + // remove temp storage from result + unset($resultLv[$idx]['__condition']); + unset($resultLv[$idx]['__parent']); + } + + if ($cnd->toListviewColumn($resultLv, $extraCols)) + $this->extendGlobalData($cnd->getJsGlobals()); + + $tabData = ['data' => array_values($resultLv)]; + + if ($extraCols) + { + $tabData['extraCols'] = $extraCols; $tabData['hiddenCols'] = ['instancetype']; } @@ -1107,35 +1065,55 @@ class SpellPage extends GenericPage } } - // tab: taught by npc (source:6 => trainer) - if (!empty($this->subject->sources[$this->typeId][6])) + // tab: taught by npc + if ($this->subject->getSources($s) && in_array(SRC_TRAINER, $s)) { - $src = $this->subject->sources[$this->typeId][6]; - $list = []; - if (count($src) == 1 && $src[0] == 1) // multiple trainer - { - $list = DB::World()->selectCol(' - SELECT cdt.CreatureId - FROM creature_default_trainer cdt - JOIN trainer_spell ts ON ts.TrainerId = cdt.TrainerId - WHERE ts.SpellId = ?d', - $this->typeId - ); - } - else if ($src) - $list = array_values($src); + $trainers = DB::World()->select(' + SELECT cdt.CreatureId AS ARRAY_KEY, ts.ReqSkillLine AS reqSkillId, ts.ReqSkillRank AS reqSkillValue, ts.ReqLevel AS reqLevel, ts.ReqAbility1 AS reqSpellId1, ts.reqAbility2 AS reqSpellId2 + FROM creature_default_trainer cdt + JOIN trainer_spell ts ON ts.TrainerId = cdt.TrainerId + WHERE ts.SpellId = ?d', + $this->typeId + ); - if ($list) + if ($trainers) { - $tbTrainer = new CreatureList(array(Cfg::get('SQL_LIMIT_NONE'), ['ct.id', $list], ['s.guid', null, '!'], ['ct.npcflag', 0x10, '&'])); + $tbTrainer = new CreatureList(array(Cfg::get('SQL_LIMIT_NONE'), ['ct.id', array_keys($trainers)], ['s.guid', null, '!'], ['ct.npcflag', NPC_FLAG_TRAINER, '&'])); if (!$tbTrainer->error) { $this->extendGlobalData($tbTrainer->getJSGlobals()); - $this->lvTabs[] = [CreatureList::$brickFile, array( - 'data' => array_values($tbTrainer->getListviewData()), + + $cnd = new Conditions(); + $skill = $this->subject->getField('skill'); + + foreach ($trainers as $tId => $train) + { + if ($_ = $train['reqLevel']) + $cnd->addExternalCondition(Conditions::SRC_NONE, $tId, [Conditions::LEVEL, $_, Conditions::OP_GT_E]); + + if ($_ = $train['reqSkillId']) + if (count($skill) == 1 && $_ != $skill[0]) + $cnd->addExternalCondition(Conditions::SRC_NONE, $tId, [Conditions::SKILL, $_, $train['reqSkillValue']]); + + for ($i = 1; $i < 3; $i++) + if ($_ = $train['reqSpellId'.$i]) + $cnd->addExternalCondition(Conditions::SRC_NONE, $tId, [Conditions::SPELL, $_]); + } + + $lvData = $tbTrainer->getListviewData(); + if ($cnd->toListviewColumn($lvData, $extraCols)) + $this->extendGlobalData($cnd->getJsGlobals()); + + $lvTab = array( + 'data' => array_values($lvData), 'id' => 'taught-by-npc', 'name' => '$LANG.tab_taughtby', - )]; + ); + + if ($extraCols) + $lvTab['extraCols'] = $extraCols; + + $this->lvTabs[] = [CreatureList::$brickFile, $lvTab]; } } } @@ -1261,20 +1239,19 @@ class SpellPage extends GenericPage // taughtbyitem // tab: conditions - $sc = Util::getServerConditions([CND_SRC_SPELL_LOOT_TEMPLATE, CND_SRC_SPELL_IMPLICIT_TARGET, CND_SRC_SPELL, CND_SRC_SPELL_CLICK_EVENT, CND_SRC_VEHICLE_SPELL, CND_SRC_SPELL_PROC], null, $this->typeId); - if (!empty($sc[0])) + $cnd = new Conditions(); + if ($cnd->getBySourceEntry($this->typeId, Conditions::SRC_SPELL_LOOT_TEMPLATE, Conditions::SRC_SPELL_IMPLICIT_TARGET, Conditions::SRC_SPELL, Conditions::SRC_SPELL_CLICK_EVENT, Conditions::SRC_VEHICLE_SPELL, Conditions::SRC_SPELL_PROC)) { - $this->extendGlobalData($sc[1]); - $tab = ""; + $this->extendGlobalData($cnd->getJsGlobals()); + $this->lvTabs[] = $cnd->toListviewTab(); + } - $this->lvTabs[] = [null, array( - 'data' => $tab, - 'id' => 'conditions', - 'name' => '$LANG.requires' - )]; + // tab: condition for + $cnd = new Conditions(); + if ($cnd->getByCondition(Type::SPELL, $this->typeId)) + { + $this->extendGlobalData($cnd->getJsGlobals()); + $this->lvTabs[] = $cnd->toListviewTab('condition-for', '$LANG.tab_condition_for'); } } diff --git a/pages/zone.php b/pages/zone.php index 58c39a80..4e56cf08 100644 --- a/pages/zone.php +++ b/pages/zone.php @@ -631,32 +631,24 @@ class ZonePage extends GenericPage $this->extendGlobalData($fish->jsGlobals); $xCols = array_merge(['$Listview.extraCols.percent'], $fish->extraCols); - foreach ($fish->iterate() as $lv) - { - if (!$lv['quest']) - continue; - - $xCols = array_merge($xCols, ['$Listview.extraCols.condition']); - - $reqQuest[$lv['id']] = 0; - - $lv['condition'][0][$this->typeId][] = [[CND_QUESTTAKEN, &$reqQuest[$lv['id']]]]; - } - $note = ''; if ($skill = DB::World()->selectCell('SELECT `skill` FROM skill_fishing_base_level WHERE `entry` = ?d', $this->typeId)) $note = sprintf(Util::$lvTabNoteString, Lang::zone('fishingSkill'), Lang::formatSkillBreakpoints(Game::getBreakpointsForSkill(SKILL_FISHING, $skill), Lang::FMT_HTML)); else if ($parentArea && ($skill = DB::World()->selectCell('SELECT `skill` FROM skill_fishing_base_level WHERE `entry` = ?d', $parentArea))) $note = sprintf(Util::$lvTabNoteString, Lang::zone('fishingSkill'), Lang::formatSkillBreakpoints(Game::getBreakpointsForSkill(SKILL_FISHING, $skill), Lang::FMT_HTML)); - $this->lvTabs[] = [ItemList::$brickFile, array( + $tabData = array( 'data' => array_values($fish->getResult()), 'name' => '$LANG.tab_fishing', 'id' => 'fishing', 'extraCols' => array_unique($xCols), - 'hiddenCols' => ['side'], - 'note' => $note - )]; + 'hiddenCols' => ['side'] + ); + + if ($note) + $tabData['note'] = $note; + + $this->lvTabs[] = [ItemList::$brickFile, $tabData]; } // tab: spells @@ -668,93 +660,38 @@ class ZonePage extends GenericPage $lvSpells = $spells->getListviewData(); $this->extendGlobalData($spells->getJSGlobals()); - $extra = false; + $cnd = new Conditions(); foreach ($saData as $a) { if (empty($lvSpells[$a['spell']])) continue; - $condition = []; if ($a['aura_spell']) - { - $this->extendGlobalIds(Type::SPELL, abs($a['aura_spell'])); - $condition[0][$this->typeId][] = [[$a['aura_spell'] > 0 ? CND_AURA : -CND_AURA, abs($a['aura_spell'])]]; - } + $cnd->addExternalCondition(Conditions::SRC_NONE, $a['spell'], [$a['aura_spell'] > 0 ? Conditions::AURA : -Conditions::AURA, abs($a['aura_spell'])]); if ($a['quest_start']) // status for quests needs work - { - $this->extendGlobalIds(Type::QUEST, $a['quest_start']); - $group = []; - for ($i = 0; $i < 7; $i++) - { - if (!($a['quest_start_status'] & (1 << $i))) - continue; - - if ($i == 0) - $group[] = [CND_QUEST_NONE, $a['quest_start']]; - else if ($i == 1) - $group[] = [CND_QUEST_COMPLETE, $a['quest_start']]; - else if ($i == 3) - $group[] = [CND_QUESTTAKEN, $a['quest_start']]; - else if ($i == 6) - $group[] = [CND_QUESTREWARDED, $a['quest_start']]; - } - - if ($group) - $condition[0][$this->typeId][] = $group; - } + $cnd->addExternalCondition(Conditions::SRC_NONE, $a['spell'], [Conditions::QUESTSTATE, $a['quest_start'], $a['quest_start_status']]); if ($a['quest_end'] && $a['quest_end'] != $a['quest_start']) - { - $this->extendGlobalIds(Type::QUEST, $a['quest_end']); - $group = []; - for ($i = 0; $i < 7; $i++) - { - if (!($a['quest_end_status'] & (1 << $i))) - continue; - - if ($i == 0) - $group[] = [-CND_QUEST_NONE, $a['quest_end']]; - else if ($i == 1) - $group[] = [-CND_QUEST_COMPLETE, $a['quest_end']]; - else if ($i == 3) - $group[] = [-CND_QUESTTAKEN, $a['quest_end']]; - else if ($i == 6) - $group[] = [-CND_QUESTREWARDED, $a['quest_end']]; - } - - if ($group) - $condition[0][$this->typeId][] = $group; - } + $cnd->addExternalCondition(Conditions::SRC_NONE, $a['spell'], [Conditions::QUESTSTATE, $a['quest_end'], $a['quest_end_status']]); if ($a['racemask']) - { - $foo = []; - for ($i = 0; $i < 11; $i++) - if ($a['racemask'] & (1 << $i)) - $foo[] = $i + 1; - - $this->extendGlobalIds(Type::CHR_RACE, ...$foo); - $condition[0][$this->typeId][] = [[CND_RACE, $a['racemask']]]; - } + $cnd->addExternalCondition(Conditions::SRC_NONE, $a['spell'], [Conditions::CHR_RACE, $a['racemask']]); if ($a['gender'] != 2) // 2: both - $condition[0][$this->typeId][] = [[CND_GENDER, $a['gender'] + 1]]; - - if ($condition) - { - $extra = true; - $lvSpells[$a['spell']] = array_merge($lvSpells[$a['spell']], ['condition' => $condition]); - } + $cnd->addExternalCondition(Conditions::SRC_NONE, $a['spell'], [Conditions::GENDER, $a['gender']]); } + if ($cnd->toListviewColumn($lvSpells, $extraCols)) + $this->extendGlobalData($cnd->getJsGlobals()); + $tabData = array( 'data' => array_values($lvSpells), 'hiddenCols' => ['skill'] ); - if ($extra) - $tabData['extraCols'] = ['$Listview.extraCols.condition']; + if ($extraCols) + $tabData['extraCols'] = $extraCols; $this->lvTabs[] = [SpellList::$brickFile, $tabData]; } @@ -782,21 +719,18 @@ class ZonePage extends GenericPage $areaIds[] = $this->typeId; $soundIds = []; - $zoneMusic = DB::Aowow()->select(' - SELECT - x.soundId AS ARRAY_KEY, x.soundId, x.worldStateId, x.worldStateValue, x.type - FROM ( - SELECT ambienceDay AS soundId, worldStateId, worldStateValue, 1 AS `type` FROM ?_zones_sounds WHERE id IN (?a) AND ambienceDay > 0 UNION - SELECT ambienceNight AS soundId, worldStateId, worldStateValue, 1 AS `type` FROM ?_zones_sounds WHERE id IN (?a) AND ambienceNight > 0 UNION - SELECT musicDay AS soundId, worldStateId, worldStateValue, 2 AS `type` FROM ?_zones_sounds WHERE id IN (?a) AND musicDay > 0 UNION - SELECT musicNight AS soundId, worldStateId, worldStateValue, 2 AS `type` FROM ?_zones_sounds WHERE id IN (?a) AND musicNight > 0 UNION - SELECT intro AS soundId, worldStateId, worldStateValue, 3 AS `type` FROM ?_zones_sounds WHERE id IN (?a) AND intro > 0 - ) x - GROUP BY - x.soundId, x.worldStateId, x.worldStateValue - ', $areaIds, $areaIds, $areaIds, $areaIds, $areaIds); + $zoneMusic = DB::Aowow()->select( + 'SELECT x.soundId AS ARRAY_KEY, x.soundId, x.worldStateId, x.worldStateValue, x.type + FROM (SELECT `ambienceDay` AS soundId, `worldStateId`, `worldStateValue`, 1 AS `type` FROM ?_zones_sounds WHERE `id` IN (?a) AND `ambienceDay` > 0 UNION + SELECT `ambienceNight` AS soundId, `worldStateId`, `worldStateValue`, 1 AS `type` FROM ?_zones_sounds WHERE `id` IN (?a) AND `ambienceNight` > 0 UNION + SELECT `musicDay` AS soundId, `worldStateId`, `worldStateValue`, 2 AS `type` FROM ?_zones_sounds WHERE `id` IN (?a) AND `musicDay` > 0 UNION + SELECT `musicNight` AS soundId, `worldStateId`, `worldStateValue`, 2 AS `type` FROM ?_zones_sounds WHERE `id` IN (?a) AND `musicNight` > 0 UNION + SELECT `intro` AS soundId, `worldStateId`, `worldStateValue`, 3 AS `type` FROM ?_zones_sounds WHERE `id` IN (?a) AND `intro` > 0) x + GROUP BY x.soundId, x.worldStateId, x.worldStateValue', + $areaIds, $areaIds, $areaIds, $areaIds, $areaIds + ); - if ($sSpawns = DB::Aowow()->selectCol('SELECT typeId FROM ?_spawns WHERE areaId = ?d AND type = ?d', $this->typeId, Type::SOUND)) + if ($sSpawns = DB::Aowow()->selectCol('SELECT `typeId` FROM ?_spawns WHERE `areaId` = ?d AND `type` = ?d', $this->typeId, Type::SOUND)) $soundIds = array_merge($soundIds, $sSpawns); if ($zoneMusic) @@ -817,7 +751,7 @@ class ZonePage extends GenericPage foreach ($soundIds as $sId) if (!empty($zoneMusic[$sId]['worldStateId'])) - $data[$sId]['condition'][0][$this->typeId][] = [[CND_WORLD_STATE, $zoneMusic[$sId]['worldStateId'], $zoneMusic[$sId]['worldStateValue']]]; + Conditions::extendListviewRow($data[$sId], Conditions::SRC_NONE, $this->typeId, [Conditions::WORLD_STATE, $zoneMusic[$sId]['worldStateId'], $zoneMusic[$sId]['worldStateValue']]); } $tabData['data'] = array_values($data); @@ -826,28 +760,27 @@ class ZonePage extends GenericPage $this->extendGlobalData($music->getJSGlobals(GLOBALINFO_SELF)); + $typeFilter = function(array $music, int $type) use ($data) : array + { + $result = []; + foreach (array_filter($music, function ($x) use ($type) { return $x['type'] == $type; } ) as $sId => $_) + $result = array_merge($result, $data[$sId]['files'] ?? []); + + return $result; + }; + // audio controls // ambience - if ($sounds = array_filter($zoneMusic, function ($x) { return $x['type'] == 1; } )) - foreach ($sounds as $sId => $_) - if (!empty($data[$sId]['files'])) - foreach ($data[$sId]['files'] as $f) - $this->zoneMusic['ambience'][] = $f; + if ($_ = $typeFilter($zoneMusic, 1)) + $this->zoneMusic['ambience'] = $_; // music - if ($sounds = array_filter($zoneMusic, function ($x) { return $x['type'] == 2; } )) - foreach ($sounds as $sId => $_) - if (!empty($data[$sId]['files'])) - foreach ($data[$sId]['files'] as $f) - $this->zoneMusic['music'][] = $f; + if ($_ = $typeFilter($zoneMusic, 2)) + $this->zoneMusic['music'] = $_; // intro - if ($sounds = array_filter($zoneMusic, function ($x) { return $x['type'] == 3; } )) - foreach ($sounds as $sId => $_) - if (!empty($data[$sId]['files'])) - foreach ($data[$sId]['files'] as $f) - $this->zoneMusic['intro'][] = $f; - + if ($_ = $typeFilter($zoneMusic, 3)) + $this->zoneMusic['intro'] = $_; } } } diff --git a/setup/tools/filegen/profiler.func.php b/setup/tools/filegen/profiler.func.php index bfda47ea..3646f9d3 100644 --- a/setup/tools/filegen/profiler.func.php +++ b/setup/tools/filegen/profiler.func.php @@ -200,7 +200,7 @@ if (!CLI) ); $mountz = new SpellList($condition); - $conditionSet = DB::World()->selectCol('SELECT SourceEntry AS ARRAY_KEY, ConditionValue1 FROM conditions WHERE SourceTypeOrReferenceId = ?d AND ConditionTypeOrReference = ?d AND SourceEntry IN (?a)', CND_SRC_SPELL, CND_SKILL, $mountz->getFoundIDs()); + $conditionSet = DB::World()->selectCol('SELECT SourceEntry AS ARRAY_KEY, ConditionValue1 FROM conditions WHERE SourceTypeOrReferenceId = ?d AND ConditionTypeOrReference = ?d AND SourceEntry IN (?a)', Conditions::SRC_SPELL, Conditions::SKILL, $mountz->getFoundIDs()); // get mounts for exclusion foreach ($conditionSet as $mount => $skill) @@ -212,7 +212,7 @@ if (!CLI) } foreach ($mountz->iterate() as $id => $_) - if (!$mountz->getSources($__, $___)) + if (!$mountz->getSources()) $exAdd(Type::SPELL, $id, PR_EXCLUDE_GROUP_UNAVAILABLE); foreach (CLISetup::$localeIds as $l) @@ -261,7 +261,7 @@ if (!CLI) $legit = DB::Aowow()->selectCol('SELECT `spellId2` FROM ?_items WHERE `class` = ?d AND `subClass` = ?d AND `spellId1` IN (?a) AND `spellId2` IN (?a)', ITEM_CLASS_MISC, 2, LEARN_SPELLS, $companionz->getFoundIDs()); foreach ($companionz->iterate() as $id => $_) - if (!$companionz->getSources($__, $___)) + if (!$companionz->getSources()) $exAdd(Type::SPELL, $id, PR_EXCLUDE_GROUP_UNAVAILABLE); foreach (CLISetup::$localeIds as $l) @@ -346,7 +346,7 @@ if (!CLI) $created = ''; foreach ($recipez->iterate() as $id => $__) { - if (!$recipez->getSources($__, $___)) + if (!$recipez->getSources()) $exAdd(Type::SPELL, $id, PR_EXCLUDE_GROUP_UNAVAILABLE); foreach ($recipez->canCreateItem() as $idx) diff --git a/static/js/global.js b/static/js/global.js index 0cf6d13e..df858451 100644 --- a/static/js/global.js +++ b/static/js/global.js @@ -8003,7 +8003,7 @@ Listview.extraCols = { condition: { id: 'condition', - name: LANG.requires, + name: LANG.tab_conditions, type: 'text', width: '25%', compute: function(row, td) { @@ -8012,12 +8012,15 @@ Listview.extraCols = { td.className = 'small'; td.style.lineHeight = '18px'; + td.style.textAlign = 'left'; + + // tiny links are hard to hit, hmkey? + td.onclick = (e) => $WH.sp(e); var mText = ConditionList.createCell(row.condition); Markup.printHtml(mText, td); return; - }, getVisibleText: function(row) { var @@ -23638,7 +23641,7 @@ function g_getIngameLink(color, id, name) { * which i intend to ignore */ -/* custom */ +/* aowow - custom */ var ConditionList = new function() { var self = this, @@ -23661,7 +23664,7 @@ var ConditionList = new function() { return _createTab(); }; - function _listing(mask, src, tpl) { + function _makeList(mask, src, tpl) { var arr = Listview.funcBox.assocBinFlags(mask, src).sort(), buff = ''; @@ -23670,7 +23673,7 @@ var ConditionList = new function() { if (len > 1 && i == len - 1) buff += LANG.or; else if (i > 0) - buff += ', '; + buff += LANG.comma; buff += $WH.sprintf(tpl, arr[i], src[arr[i]]); } @@ -23678,160 +23681,174 @@ var ConditionList = new function() { return buff; } - function _parseEntry(entry) { + function _parseEntry(entry, targets, target) { var - cnd = entry, str = '', - param = ['', null]; - strIdx = Math.abs(entry[0]); + negate = false, + strIdx = 0, + param = []; - if (strIdx == 22 || strIdx == 23) - strIdx = 4; - else if (strIdx == 16 || strIdx == 30 || strIdx == 32) - strIdx--; + [strIdx, ...param] = entry; + + negate = strIdx < 0; + strIdx = Math.abs(strIdx); if (!g_conditions[strIdx]) - return 'unknown condition index ' + strIdx; + return 'unknown condition index #' + strIdx; - // these cases are not (yet) handled in detail - if ($WH.in_array([13, 21, 24, 33, 34], strIdx) != -1) - return g_conditions[strIdx].replace(/\$([^\$:;]*):([^\$:;]*);/, '$' + (entry[0] > 0 ? 1 : 2)); + switch (strIdx) { + case 5: + var standings = {}; + for (let i in g_reputation_standings) + standings[i * 1 + 1] = g_reputation_standings[i]; - switch (Math.abs(entry[0])) { - case 1: - case 25: param[0] = '[spell=' + entry[1] + ']'; break; - case 2: param[1] = entry[2]; // do not break - case 3: param[0] = '[item=' + entry[1] + ']'; break; - case 4: - case 23: param[0] = '[zone=' + entry[1] + ']'; break; - case 8: - case 9: - case 14: - case 28: param[0] = '[quest=' + entry[1] + ']'; break; - case 12: param[0] = '[event=' + entry[1] + ']'; break; - case 17: param[0] = '[achievement=' + entry[1] + ']'; break; - case 18: param[0] = '[title=' + entry[1] + ']'; break; - case 6: param[0] = g_sides[entry[1]]; break; - case 10: param[0] = g_drunk_states[entry[1]]; break; - case 22: param[0] = g_zone_categories[entry[1]]; break; - case 15: param[0] = _listing(entry[1], g_chr_classes, '[class=$1]'); break; - case 16: param[0] = _listing(entry[1], g_chr_races, '[race=$1]'); break; - case 7: param[0] = '[skill=' + entry[1] + ']'; - if (entry[2]) - param[0] += $WH.sprintf(LANG.qty, entry[2]); - break; - case 5: var standings = {}; - for (i in g_reputation_standings) - standings[i * 1 + 1] = g_reputation_standings[i]; + param[1] = _makeList(entry[2], standings, '$2'); + break; + case 6: + if (entry[1] == 1) + param[0] = $WH.sprintf('[span class=icon-alliance]$1[/span]', g_sides[1]); + else if (entry[1] == 2) + param[0] = $WH.sprintf('[span class=icon-horde]$1[/span]', g_sides[2]); + else + param[0] = $WH.sprintf('[span class=icon-alliance]$1[/span]$2[span class=icon-horde]$3[/span]', g_sides[1], LANG.or, g_sides[2]); + break; + case 10: + param[0] = g_drunk_states[entry[1]] ?? 'UNK DRUNK STATE'; + break; + case 13: + param[2] = g_instance_info[entry[3]] ?? 'UNK INSTANCE INFO'; + break; + case 15: + param[0] = _makeList(entry[1], g_chr_classes, '[class=$1]'); + break; + case 16: + param[0] = _makeList(entry[1], g_chr_races, '[race=$1]'); + break; + case 20: + if (entry[1] == 0) + param[0] = $WH.sprintf('[span class=icon-$1]$2[/span]', g_file_genders[0], LANG.male); + else if (entry[1] == 1) + param[0] = $WH.sprintf('[span class=icon-$1]$2[/span]', g_file_genders[1], LANG.female); + else + param[0] = g_npc_types[10]; // not specified + break; + case 21: + var states = {}; + for (let i in g_unit_states) + states[i * 1 + 1] = g_unit_states[i]; - param[0] = '[faction=' + entry[1] + ']'; - param[1] = _listing(entry[2], standings, '$2'); - break; - case 20: if (entry[1] == 0) { - param[0] = LANG.male; - param[1] = g_file_genders[0]; - } - else if (entry[1] == 1) { - param[0] = LANG.female; - param[1] = g_file_genders[1]; - } - else - param[0] = g_npc_types[10]; - break; - case 29: param[0] = '[npc=' + entry[1] + ']'; - param[1] = entry[2]; - break; - case 30: param[0] = '[object=' + entry[1] + ']'; - param[1] = entry[2]; - break; - case 31: if (entry[2] && entry[1] == 3) { - param[0] = '[npc=' + entry[2] + ']'; - break; - } - else if (entry[2] && entry[1] == 5) { - param[0] = '[object=' + entry[2] + ']'; - break; - } - else // create mask from id and resolve in case 32 - entry[1] = (1 << entry[1]); - case 32: param[0] = _listing(entry[1], g_world_object_types, '$2'); break; - case 36: break; + param[0] = _makeList(entry[1], states, '$2'); + break; + case 22: + if (entry[2]) + param[0] = '[zone=' + entry[2] + ']'; + else + param[0] = g_zone_categories[entry[1]] ?? 'UNK ZONE'; + break; + case 24: + param[0] = g_npc_types[entry[1]] ?? 'UNK NPC TYPE'; + break; + case 26: + var idx = 0, buff = []; + while (entry[1] >= (1 << idx)) { + if (!(entry[1] & (1 << idx++))) + continue; + + buff.push(idx); + } + param[0] = buff ? buff.join(LANG.comma) : ''; + break; case 27: case 37: - case 38: param[0] = entry[1]; - param[1] = g_operators[entry[2]]; - break; - case 35: param[0] = entry[2]; - param[1] = g_operators[entry[3]]; - break; - case 11: param[0] = entry[1]; - param[1] = entry[2]; - break; - case 26: - var pIndex = 0; - while (entry[1]) { - if (entry[1] & (1 << pIndex)) { - if (param[0]) - param[0] += ', '; + case 38: + param[1] = g_operators[entry[2]]; + break; + case 31: + if (entry[2] && entry[1] == 3) + param[0] = '[npc=' + entry[2] + ']'; + else if (entry[2] && entry[1] == 5) + param[0] = '[object=' + entry[2] + ']'; + else + param[0] = g_world_object_types[entry[1]] ?? 'UNK TYPEID'; + break; + case 32: + var objectTypes = {}; + for (let i in g_world_object_types) + objectTypes[i * 1 + 1] = g_world_object_types[i]; - param[0] += pIndex + 1; - entry[1] &= ~(1 << pIndex); - } - pIndex++; - } + param[0] = _makeList(entry[1], objectTypes, '$2'); + break; + case 33: + param[0] = targets[entry[1]]; + param[1] = g_relation_types[entry[2]] ?? 'UNK RELATION'; + param[2] = targets[target]; + break; + case 34: + param[0] = targets[entry[1]]; + + var standings = {}; + for (let i in g_reputation_standings) + standings[i * 1 + 1] = g_reputation_standings[i]; + param[1] = _makeList(entry[2], standings, '$2'); + break; + case 35: + param[0] = targets[entry[1]]; + param[2] = g_operators[entry[3]]; + break; + case 42: + if (!entry[1]) + param[0] = g_stand_states[entry[2]] ?? 'UNK STAND_STATE'; + else if (entry[1] == 1) + param[0] = g_stand_states[entry[2] ? 1 : 0]; + else + param[0] = ''; + break; + case 47: + var quest_states = {}; + for (let i in g_quest_states) + quest_states[i * 1 + 1] = g_quest_states[i]; + + param[1] = _makeList(entry[2], quest_states, '$2'); + break; } str = g_conditions[strIdx]; - // resolve nagation - str = str.replace(/\$([^\$:;]*):([^\$:;]*);/, '$' + (entry[0] > 0 ? 1 : 2)); + // fill in params + str = $WH.sprintfa(str, param[0], param[1], param[2]); - // resolve params - return $WH.sprintf(str, param[0], param[1]); + // resolve NegativeCondition + str = str.replace(/\$N([^:]*):([^;]*);/g, '$' + (negate > 0 ? 2 : 1)); + + // resolve vars + return str.replace(/\$C(\d+)([^:]*):([^;]*);/g, (_, i, y, n) => (i > 0 ? y : n)); } function _createTab() { var - nTabs = Object.keys(_conditions).length, - nSubTabs = [], buff = ''; - for (g in _conditions) { - nSubTabs[g] = Object.keys(_conditions[g]).length; - if (nSubTabs[g] > 1) - nTabs += nSubTabs[g]; - } - - if (nTabs > 1) - buff += '[tabs name=conditionSource]'; - // tabs for conditionsTypes for (g in _conditions) { - if (!g_condition_types[g]) + if (!g_condition_sources[g]) continue; - var nSubTypes = Object.keys(_conditions[g]).length; - + let k = 0; for (h in _conditions[g]) { var - srcGrp = h.split(':'); + srcGroup, srcEntry, srcId, target, + targets, desc, nGroups = Object.keys(_conditions[g][h]).length, curGroup = 1; - if (nTabs > 1) { - if (nSubTabs[g] > 1) { - // only set for NPCs - var sName = srcGrp[1]; - if ($WH.in_array([18, 21, 23], g) != -1) - sName = g_npcs[srcGrp[1]]['name_' + Locale.getName()]; + [srcGroup, srcEntry, srcId, target] = h.split(':').map((x) => parseInt(x)); + [targets, desc] = g_condition_sources[g]; - buff += '[tab name="' + g_condition_types[g][0] + ' (' + sName + ')"]'; - } - else - buff += '[tab name="' + g_condition_types[g][0] + '"]'; - } + // resolve targeting + let src = desc.replace(/\$T([^:]*):([^;]*);/, (_, t1, t2) => (target ? t2 : t1).replace('%', targets[target])); + let rand = $WH.rs(); - buff += '[h3]' + $WH.sprintf(g_condition_types[g][1], srcGrp[0], srcGrp[1] || '') + '[/h3]'; + buff += '[h3][toggler' + (k ? '=hidden' : '') + ' id=' + rand + ']' + $WH.sprintfa(src, srcGroup, srcEntry, srcId) + '[/toggler][/h3][div' + (k++ ? '=hidden' : '') + ' id=' + rand + ']'; if (nGroups > 1) { buff += LANG.note_condition_group + '[br][br]'; @@ -23845,13 +23862,15 @@ var ConditionList = new function() { nEntries = Object.keys(_conditions[g][h][i]).length; if (nGroups <= 1 && nEntries > 1) - buff += LANG.note_condition + '[br][br]'; + buff += '[div style="padding-left:15px"]' + LANG.note_condition + '[/div]'; if (nGroups > 1) buff += '[tr][td width=70px valign=middle align=center]' + LANG.group + ' ' + (curGroup++) + LANG.colon + '[/td][td]'; // individual conditions + buff += '[ol]'; for (j in group) - buff += _parseEntry(group[j]) + '[br]'; + buff += '[li]' + _parseEntry(group[j], targets, target) + '[/li]'; + buff += '[/ol]'; if (nGroups > 1) buff += '[/td][/tr]'; @@ -23860,14 +23879,10 @@ var ConditionList = new function() { if (nGroups > 1) buff += '[/tr][/table]'; - if (nTabs > 1) - buff += '[/tab]'; + buff += '[/div]'; } } - if (nTabs > 1) - buff += '[/tabs]'; - return buff; } @@ -23875,37 +23890,51 @@ var ConditionList = new function() { var rows = []; // tabs for conditionsTypes - for (g in _conditions) { - for (h in _conditions[g]) { + for (let g in _conditions) { + if (!g_condition_sources[g]) + continue; + + for (let h in _conditions[g]) { + var + target, targets, + + [, , , target] = h.split(':').map((x) => parseInt(x)); + [targets, ] = g_condition_sources[g]; + + let nElseGroups = Object.keys(_conditions[g][h]).length // table for elseGroups - for (i in _conditions[g][h]) { - var + for (let i in _conditions[g][h]) { + let subGroup = [], group = _conditions[g][h][i], - nEntries = Object.keys(_conditions[g][h][i]).length; + nEntries = Object.keys(_conditions[g][h][i]).length + buff = ''; + + if (nElseGroups > 1) + { + let rand = $WH.rs(); + buff += '[toggler' + (i > 0 ? '=hidden' : '') + ' id=cell-' + rand + ']' + (i > 0 ? LANG.cnd_or : LANG.cnd_either) + '[/toggler][div' + (i > 0 ? '=hidden' : '') + ' id=cell-' + rand + ']'; + } // individual conditions - for (j in group) { - if (nEntries > 1) - subGroup.push(_parseEntry(group[j])); - else - rows.push(_parseEntry(group[j])); + for (let j in group) { + subGroup.push(_parseEntry(group[j], targets, target)); } - if (subGroup.length) { - var buff = ''; - for (j in subGroup) { - if (j > 0 && j == subGroup.length - 1) - buff += LANG.and; - else if (j > 0) - buff += ', '; + for (j in subGroup) { + if (nEntries > 1 && j > 0 && j == subGroup.length - 1) + buff += LANG.and + '[br]'; + else if (nEntries > 1 && j > 0) + buff += ',[br]'; - buff += subGroup[j]; - } - - rows.push(buff); + buff += subGroup[j]; } + + if (nElseGroups > 1) + buff += '[/div]'; + + rows.push(buff); } } } diff --git a/static/js/locale_dede.js b/static/js/locale_dede.js index 9ab0aaa7..83128646 100644 --- a/static/js/locale_dede.js +++ b/static/js/locale_dede.js @@ -2407,67 +2407,158 @@ var g_world_object_types = { 7: 'Spielerleiche' }; -var g_condition_types = { - 1: ['Plündern', 'Wenn die Bedingung erfüllt ist, kann dieser Gegenstand aus [npc=$1] geplündert werden.'], // CND_SRC_CREATURE_LOOT_TEMPLATE - 2: ['Entzaubern', 'Wenn die Bedingung erfüllt ist, kann dieser Gegenstand aus [item=$1] entzaubert werden.'], // CND_SRC_DISENCHANT_LOOT_TEMPLATE - 3: ['Angeln', 'Wenn die Bedingung erfüllt ist, kann dieser Gegenstand beim Angeln in [zone=$1] gefunden werden.'], // CND_SRC_FISHING_LOOT_TEMPLATE - 4: ['Objekt Öffnen', 'Wenn die Bedingung erfüllt ist, kann dieser Gegenstand in [object=$1] gefunden werden.'], // CND_SRC_GAMEOBJECT_LOOT_TEMPLATE - 5: ['Gegenst. Öffnen', 'Wenn die Bedingung erfüllt ist, kann dieser Gegenstand in [item=$1] gefunden werden.'], // CND_SRC_ITEM_LOOT_TEMPLATE - 6: ['Brief Anhang', 'Wenn die Bedingung erfüllt ist, kann dieser Gegenstand an diesem Brief angehängt sein.'], // CND_SRC_MAIL_LOOT_TEMPLATE - 7: ['Mahlen', 'Wenn die Bedingung erfüllt ist, kann dieser Gegenstand beim Mahlen von [item=$1] gefunden werden.'], // CND_SRC_MILLING_LOOT_TEMPLATE - 8: ['Stehlen', 'Wenn die Bedingung erfüllt ist, kann dieser Gegenstand von [npc=$1] gesammelt werden.'], // CND_SRC_PICKPOCKETING_LOOT_TEMPLATE - 9: ['Sondieren', 'Wenn die Bedingung erfüllt ist, kann dieser Gegenstand beim Sondieren von [item=$1] gefunden werden.'], // CND_SRC_PROSPECTING_LOOT_TEMPLATE - 10: ['Ref. Plündern', ''], // CND_SRC_REFERENCE_LOOT_TEMPLATE - 11: ['Kürschnern', 'Wenn die Bedingung erfüllt ist, kann dieser Gegenstand beim Kürschnern von [item=$1] gefunden werden.'], // CND_SRC_SKINNING_LOOT_TEMPLATE - 12: ['Herstellen', 'Wenn die Bedingung erfüllt ist, kann beim Wirken von [spell=$1] zusätzlich dieser Gegenstand erzeugt werden.'], // CND_SRC_SPELL_LOOT_TEMPLATE - 13: ['Autom. Zielwahl', 'Nur Ziele, welche diese Bedinungen erfüllen, können von diesem Zauber betroffen sein.'], // CND_SRC_SPELL_IMPLICIT_TARGET - 14: ['Dialog', 'Zeige den verwandten Dialog, wenn die Bedingungen erfüllt sind.'], // CND_SRC_GOSSIP_MENU - 15: ['Dialog Menü', 'Zeige das verwandte Dialogmenü, wenn die Bedingungen erfüllt sind.'], // CND_SRC_GOSSIP_MENU_OPTION - 16: ['Vehicle', 'Diese Kreatur kann als Fahrzeug benutzt werden, wenn die Bedingungen erfüllt sind.'], // CND_SRC_CREATURE_TEMPLATE_VEHICLE - 17: ['Zauber', 'Der Zauber kann nur gewirkt werden, wenn die Bedingungen erfüllt sind.'], // CND_SRC_SPELL - 18: ['Klick', 'Wenn die Bedingung erfüllt ist, wirkt [npc=$2] [spell=$1], wenn man darauf klickt.'], // CND_SRC_SPELL_CLICK_EVENT - 19: ['Quest Annahme', 'Der Spieler kann dieses Quest annehmen, wenn die Bedingungen erfüllt sind.'], // CND_SRC_QUEST_SHOW_MARK - 20: ['Quest Symbol', 'Ein [icon name=quest_startend] [/icon] wird für dieses Quest angezeigt, wenn die Bedingungen erfüllt sind.'], // CND_SRC_QUEST_ACCEPT - 21: ['Fahrzeug Fähigk.', 'Wenn die Bedingung erfüllt ist, ist im Fahrzeug [npc=$2] [spell=$1] verfügbar'], // CND_SRC_VEHICLE_SPELL - 22: ['SmartAI', 'Wenn die Bedingung erfüllt ist, kann die KI dieser Kreatur zusätzliche Handlungen durchführen.'], // CND_SRC_SMART_EVENT - 23: ['Händler', 'Wenn die Bedingung erfüllt ist, hat der Händler diesen Gegenstand im Sortiment.'], // CND_SRC_NPC_VENDOR - 24: ['Zauberauslösung', 'Wenn die Bedingung erfüllt ist, kann der Zauber auslösen.'] // CND_SRC_SPELL_PROC +var g_instance_info = { + 0: 'Data', + 1: 'GUID', + 2: 'Bosszustand', + 3: 'Data64' +}; + +var g_unit_states = { + 0: 'Gestorben', + 1: 'Angreifend', + 2: 'Bezaubert', + 3: 'Betäubt', + 4: 'Umherwandernd', + 5: 'Verfolgend', + 6: 'Fokussiert', + 7: 'Fliehend', + 8: 'Im Flug', + 9: 'Folgend', + 10: 'Festegewurzelt', + 11: 'Verwirrt', + 12: 'Abgelenkt', + 13: 'Isoliert', + 14: 'Spieler angreifend', + 15: 'Zaubernd', + 16: 'Besessen', + 17: 'Anstürmend', + 18: 'Springend', + 19: 'In Formation folgend', + 20: 'In Bewegung', + 21: 'In Rotation', + 22: 'Entkommend', + 23: 'Umherwandernde Bewegung', + 24: 'Verwirrte Bewegung', + 25: 'Fliehende Bewegung', + 26: 'Verfolgende Bewegung', + 27: 'Folgende Bewegung', + 28: 'Ignoriere Wegfindung', + 29: 'In Formation folgende Bewegung' +}; + +var g_relation_types = { + 0: 'ist$N: nicht; sich selbst', + 1: 'ist$N: nicht; in einer Gruppe mit $3', + 2: 'ist$N: nicht; in einem Raid oder Gruppe mit $3', + 3: 'ist$N: nicht; im Besitz von $3', + 4: 'ist$N: kein; Passagier von $3', + 5: 'wurde$N: nicht; von $3 beschworen' +}; + +var g_stand_states = { + 0: 'steht$N: nicht;', + 1: 'sitzt$N: nicht;', + 2: 'sitzt$N: nicht; auf einem Stuhl', + 3: 'schläft$N: nicht;', + 4: 'sitzt$N: nicht; auf einem niedrigen Stuhl', + 5: 'sitzt$N: nicht; auf einem mittleren Stuhl', + 6: 'sitzt$N: nicht; auf einem hohen Stuhl', + 7: 'ist$N: nicht; tot', + 8: 'knieht$N: nicht;', + 9: 'ist$N: nicht; untergetaucht' +}; + +var g_quest_states = { + 0: 'bisher nicht gesehen', + 1: 'abgeschlossen', + 3: 'angenommen', + 5: 'versagt', + 6: 'Belohnungen erhalten', +}; + +var g_condition_sources = { + 0: [['Spieler', null], ''], + 1: [['Spieler', null], 'Wenn die Bedingung erfüllt ist kann [item=$2] aus [npc=$1] geplündert werden.'], + 2: [['Spieler', null], 'Wenn die Bedingung erfüllt ist kann [item=$2] aus [item=$1] entzaubert werden.'], + 3: [['Spieler', null], 'Wenn die Bedingung erfüllt ist kann [item=$2] beim Angeln in [zone=$1] gefunden werden.'], + 4: [['Spieler', null], 'Wenn die Bedingung erfüllt ist kann [item=$2] in [object=$1] gefunden werden.'], + 5: [['Spieler', null], 'Wenn die Bedingung erfüllt ist kann [item=$2] in [item=$1] gefunden werden.'], + 6: [['Spieler', null], 'Wenn die Bedingung erfüllt ist kann [item=$2] an den Brief aus [quest=$1] angehängt sein.'], + 7: [['Spieler', null], 'Wenn die Bedingung erfüllt ist kann [item=$2] beim Mahlen von [item=$1] gefunden werden.'], + 8: [['Spieler', null], 'Wenn die Bedingung erfüllt ist kann [item=$2] von [npc=$1] gestohlen werden.'], + 9: [['Spieler', null], 'Wenn die Bedingung erfüllt ist kann [item=$2] beim Sondieren von [item=$1] gefunden werden.'], + 10: [['Spieler', null], 'Wenn die Bedingung erfüllt ist kann [item=$2] im Template #$1 referenziert werden.'], + 11: [['Spieler', null], 'Wenn die Bedingung erfüllt ist kann [item=$2] von [npc=$1] gesammelt werden.'], + 12: [['Spieler', null], 'Wenn die Bedingung erfüllt ist kann beim Wirken von [spell=$1] zusätzlich [item=$2] erzeugt werden.'], + 13: [['Ziel', 'Zauberer'], 'Nur ein $T% welches:% welcher; die Bedingung erfüllt, kann von [spell=$2] betroffen sein.'], + 14: [['Spieler', 'Entität'], 'Zeige Dialogtext #$2 aus Menu #$1, wenn $Tder %:die %; die Bedingung erfüllt.'], + 15: [['Spieler', 'Entität'], 'Zeige Dialogoption #$2 aus Menu #$1, wenn $Tder %:die %; die Bedingung erfüllt.'], + 16: [['Spieler', 'Kreatur'], '[npc=$2] kann als Fahrzeug benutzt werden, wenn $Tder %:es; die Bedingung erfüllt.'], + 17: [['Zauberer', 'Ziel'], '[spell=$2] kann nur dann gewirkt werden, wenn $Tder %:das %; die Bedingung erfüllt.'], + 18: [['Spieler', 'Kreatur'], 'Wenn $Tdie %:der %; die Bedingung erfüllt wirkt [npc=$1] [spell=$2], wenn angeklickt.'], + 19: [['Spieler', null], 'Wenn die Bedingung erfüllt ist kann [quest=$2] angenommen werden.'], + 20: [['Spieler', null], 'Wenn die Bedingung erfüllt ist wird ein [icon name=quest_startend] [/icon] für [quest=$2] angezeigt.'], + 21: [['Spieler', 'Kreatur'], 'Fahrzeug [npc=$1] verfügt über [spell=$2], wenn $Tder %:es; die Bedingung erfüllt.'], + 22: [['Auslöser', 'Entität'], 'Wenn $Tder %:die %; die Bedingung erfüllt kann die KI zusätzliche Handlungen durchführen.'], + 23: [['Spieler', 'Kreatur'], 'Wenn $Tder %:die %; die Bedingung erfüllt hat [npc=$1] [item=$2] im Sortiment.'], + 24: [['Zauberer', 'Ziel'], 'Wenn $Tder %:das %; die Bedingung erfüllt kann [spell=$2] auslösen.'], + 30: [['Spieler', null], 'Wenn die Bedingung erfüllt ist kann [url=?areatrigger=$2]Areatrigger #$2[/url] ausgelöst werden.'] }; var g_conditions = { - 1: 'Der Spieler hat $eine:keine; Aura von $1', - 2: 'Der Spieler besitzt$: nicht; $1', - 3: 'Der Spieler hat$: nicht; $1 ausgerüstet', - 4: 'Der Spieler befindet sich$: nicht; in $1', // also used by 22, 23 - 5: 'Der Ruf bei $1 ist$: nicht; $2', - 6: 'Der Spieler ist$: nicht; $1', - 7: 'Der Spieler beherrscht $1$: nicht;', - 8: 'Der Spieler hat $1$: nicht; beendet', - 9: 'Der Spieler hat $1$: nicht; angenommen', - 10: 'Der Spieler ist$: nicht; $1', - 11: 'WorldState #$1 ist$: nicht; $2', - 12: '$1 ist$: nicht; aktiv', - 13: 'Die Instanz hat einen bestimmten Zustand$: nicht;', // nyi - 14: 'Der Spieler hat $nie :;mit $1 interagiert', - 15: 'Der Spieler ist$: nicht; ein $1', // also used by 16 - 17: 'Der Spieler hat $1$: nicht; erlangt', - 18: 'Der Spieler hat $1$: nicht; erhalten', - 20: 'Des Spielers Geschlecht is$: nicht; [span class=icon-$2]$1[/span]', - 21: 'Das Ziel hat einen bestimmten Zustand$: nicht;', // nyi - 24: '', // not used - 25: 'Der Spieler kennt$: nicht; $1', - 26: 'Die Kreatur befindet sich$: nicht; in Phase $1', - 27: 'Die Stufe des Ziels ist$: nicht; $2 $1', - 28: 'Der Spieler hat $1$: nicht; abgeschlossen', - 29: 'Der Spieler befindet sich$: nicht; in $2m zu $1', // also used by 30 - 31: 'Das Ziel des Zaubers ist$: nicht;: $1', // also used by 32 - 33: 'Der Spieler hat eine bestimmte Beziehung mit dem Ziel$: nicht;', // nyi - 34: 'Der Spieler hat eine bestimmte Ruf-Reaktion mit dem Ziel$: nicht;', // nyi - 35: 'Das Ziel ist$: nicht; $2 $1m entfernt', - 36: 'Das Ziel ist$: nicht; am Leben', - 37: 'Die Gesundheit des Ziels ist$: nicht; $2 $1', - 38: 'Die Gesundheit des Ziels ist$: nicht; $2 $1%' + 0: 'Immer $Nwahr:falsch;', + 1: 'Das Ziel hat $Neine:keine; Aura von [spell=$1]', + 2: 'Der Spieler hat $N:nicht; $2 [item=$1] im Inventar$C$3 oder der Bank:;', + 3: 'Der Spieler hat $N:nicht; [item=$1] ausgerüstet', + 4: 'Der Spieler befindet sich$N: nicht; in [zone=$1]', + 5: 'Des Spielers Ruf bei [faction=$1] ist$N: nicht; $2', + 6: 'Der Spieler gehört$N: nicht; der $1 an', + 7: 'Der Spieler beherrscht [skill=$1]$N: nicht;$C$2 (min. $2):;', + 8: 'Der Spieler wurde$N: nicht; für [quest=$1] entlohnt', + 9: 'Der Spieler hat $N: nicht; [quest=$1] angenommen', + 10: 'Der Spieler ist $N: nicht; $1', + 11: 'WorldState #$1 ist$N: nicht; $2', + 12: '[event=$1] findet gerade$N: nicht; statt', + 13: '$3 der Instanz auf Index #$1 ist $Ngleich:ungleich; "$2"', + 14: 'Der Spieler hat $Nniemals:; mit [quest=$1] interagiert', + 15: 'Der Spieler ist $Nein:kein; $1', + 16: 'Der Spieler ist $Nein:kein; $1', + 17: 'Der Spieler hat$N: nicht; [achievement=$1] erlangt', + 17: 'Der Spieler hat$N: nicht; [title=$1] erhalten', + 19: 'Die Spawnmaske der Entität is $Ngleich:ungleich; "$1"', + 20: 'Des Spielers Geschlecht is$N: nicht; $1', + 21: 'Der Zustand der Kreatur ist$N: nicht; $1', + 22: 'Das Ziel ist$N: nicht; in $1', + 23: 'Das Ziel ist$N: nicht; in [zone=$1]', + 24: 'Die Kreatur ist $Nein:kein; $1', + 25: 'Der Spieler kennt [spell=$1]$N: nicht;', + 26: 'Die Entität befindet sich$N: nicht; in Phase $1', + 27: 'Die Stufe des Ziels ist$N: nicht; $2 $1', + 28: 'Der Spieler hat [quest=$1]$N: nicht; abgeschlossen', + 29: 'Das Ziel befindet sich$N: nicht; innerhalb von $2m zur $C$verstorbenen:lebendigen; Kreatur [npc=$1]', + 30: 'Das Ziel befindet sich$N: nicht; innerhalb von $2m zu [object=$1]', + 31: 'Die Entität ist$N: nicht; $C$2: vom Typ; $1$C$3 (GUID $3):;', + 32: 'Die Entität ist$N: nicht; vom Typ $1', + 33: '$1 $2', // see g_relation_types + 34: 'Die Kreatur is$N: nicht; $2 gegenüber $1', + 35: 'Das Ziel ist$N: nicht; $3 $2m von $1 entfernt', + 36: 'Das Ziel ist$Nlebendig:tot;', + 37: 'Die Gesundheit des Ziels ist$N: nicht; $2 $1 Punkte', + 38: 'Die Gesundheit des Ziels ist$N: nicht; $2 $1%', + 39: '[achievement=$1] wurde auf diesem Realm$N: bisher nicht; erlangt', + 40: 'Das Ziel schwimmt gerade$N: nicht;', + 42: 'Die Kreatur $1', // negation in g_stand_states + 43: 'Der Spieler hat heute $Nbereits:noch nicht; [quest=$1] abgeschlossen', + 44: 'Die Kreatur ist$N: nicht; bezaubert', + 45: 'Der Spieler besitzt $Neinen:keinen; $C$1gezähmten:beschworenen; Begleiter', + 46: 'Der Spieler fliegt gerade$N: nicht; auf einem Taxi', + 47: 'Der Spieler hat [quest=$1]$N: nicht; $2', + 48: 'Der Questfortschritt für Ziel #$2 von [quest=$1] ist$N: nicht; $3', + 49: 'Der aktuelle Schwierigkeitsgrad für diese Instanz ist #$1', + 50: 'Der Spieler $C$1kann$N: nicht; Gamemaster sein:ist $Nein:kein; Gamemaster;' }; + /* end aowow custom */ var LANG = { @@ -4842,6 +4933,11 @@ var LANG = { /* AoWoW: start custom */ + tab_conditions: 'Bedingungen', + tab_condition_for: 'Bedingung for', + cnd_either: 'Entweder', + cnd_or: 'Oder', + // Guide myguides: 'Meine Leitfäden', listguides: 'Leitfäden auflisten', diff --git a/static/js/locale_enus.js b/static/js/locale_enus.js index ef2d4a8d..57763466 100644 --- a/static/js/locale_enus.js +++ b/static/js/locale_enus.js @@ -2441,81 +2441,172 @@ var g_drunk_states = { }; var g_operators = { - 0: 'exact', + 0: 'exactly', 1: 'more than', 2: 'less than', - 3: 'more than or exact', - 4: 'less than or exact' + 3: 'more than or exactly', + 4: 'less than or exactly' }; var g_world_object_types = { 3: 'Creature', 4: 'Player', - 5: 'Object', + 5: 'Gameobject', 7: 'Player Corpse' }; -var g_condition_types = { - 1: ['Looting', 'If the conditions are met, this item can be dropped by [npc=$1].'], // CND_SRC_CREATURE_LOOT_TEMPLATE - 2: ['Disenchanting', 'If the conditions are met, this item can be found when disenchanting [item=$1].'], // CND_SRC_DISENCHANT_LOOT_TEMPLATE - 3: ['Fishing', 'If the conditions are met, fishing in [zone=$1] can yield this item.'], // CND_SRC_FISHING_LOOT_TEMPLATE - 4: ['Object Opening', 'If the conditions are met, this item can be found in [object=$1].'], // CND_SRC_GAMEOBJECT_LOOT_TEMPLATE - 5: ['Item Opening', 'If the conditions are met, this item can be found in [item=$1].'], // CND_SRC_ITEM_LOOT_TEMPLATE - 6: ['Mail Attachm.', 'If the conditions are met, this item can be attached to this mail.'], // CND_SRC_MAIL_LOOT_TEMPLATE - 7: ['Milling', 'If the conditions are met, this item can be milled from [item=$1].'], // CND_SRC_MILLING_LOOT_TEMPLATE - 8: ['Pickpocketing', 'If the conditions are met, this item can be picked from [npc=$1].'], // CND_SRC_PICKPOCKETING_LOOT_TEMPLATE - 9: ['Prospecting', 'If the conditions are met, this item can be prospected from [item=$1].'], // CND_SRC_PROSPECTING_LOOT_TEMPLATE - 10: ['Ref. Looting', ''], // CND_SRC_REFERENCE_LOOT_TEMPLATE - 11: ['Skinning', 'If the conditions are met, this item can be skinned from [npc=$1].'], // CND_SRC_SKINNING_LOOT_TEMPLATE - 12: ['Crafting', 'If the conditions are met, casting [spell=$1] may also create this item.'], // CND_SRC_SPELL_LOOT_TEMPLATE - 13: ['Auto Target', 'Only targets matching the conditions can be affected by the spell.'], // CND_SRC_SPELL_IMPLICIT_TARGET - 14: ['Gossip', 'Display the related Gossip entry on [npc=$2], if the conditions are met.'], // CND_SRC_GOSSIP_MENU - 15: ['Gossip Menu', 'Display the related Gossip menu, if the conditions are met.'], // CND_SRC_GOSSIP_MENU_OPTION - 16: ['Vehicle', 'This Creature can be used as a vehicle, if the conditions are met.'], // CND_SRC_CREATURE_TEMPLATE_VEHICLE - 17: ['Spell', 'This Spell can only be cast, if the conditions are met.'], // CND_SRC_SPELL - 18: ['Spell Click', 'If the conditions are met, [npc=$2] casts [spell=$1] if clicked on.'], // CND_SRC_SPELL_CLICK_EVENT - 19: ['Quest Accept', 'The Player can accept this quest, if the condition is met.'], // CND_SRC_QUEST_SHOW_MARK - 20: ['Quest Sign', 'A [icon name=quest_startend] [/icon] will be shown for this quest, if the condition is met.'], // CND_SRC_QUEST_ACCEPT - 21: ['Vehicle Spell', 'If the conditions are met, vehicle [npc=$2] has [spell=$1] available.'], // CND_SRC_VEHICLE_SPELL - 22: ['SmartAI', 'If the conditions are met, the creatures AI may perform additional actions.'], // CND_SRC_SMART_EVENT - 23: ['Vendor', 'If the conditions are met, the vendor will have this item available.'], // CND_SRC_NPC_VENDOR - 24: ['Spell Proc', 'If the conditions are met, the spell is allowed to proc.'] // CND_SRC_SPELL_PROC +var g_instance_info = { + 0: 'Data', + 1: 'GUID', + 2: 'Boss State', + 3: 'Data64' +}; + +var g_unit_states = { + 0: 'Died', + 1: 'Melee attacking', + 2: 'Charmed', + 3: 'Stunned', + 4: 'Roaming', + 5: 'Chase', + 6: 'Focusing', + 7: 'Fleeing', + 8: 'In flight', + 9: 'Follow', + 10: 'Root', + 11: 'Confused', + 12: 'Distracted', + 13: 'Isolated', + 14: 'Attack player', + 15: 'Casting', + 16: 'Possessed', + 17: 'Charging', + 18: 'Jumping', + 19: 'Follow formation', + 20: 'Move', + 21: 'Rotating', + 22: 'Evade', + 23: 'Roaming move', + 24: 'Confused move', + 25: 'Fleeing move', + 26: 'Chase move', + 27: 'Follow move', + 28: 'Ignore pathfinding', + 29: 'Follow formation move' +}; + +var g_relation_types = { + 0: 'is$N: not; itself', + 1: 'is$N: not; in a group with $3', + 2: 'is$N: not; in a raid or party with $3', + 3: 'is$N: not; owned by $3', + 4: 'is$N: not; a passenger of $3', + 5: 'was$N: not; summoned by $3' +}; + +var g_stand_states = { + 0: 'standing', + 1: 'sitting', + 2: 'sitting on a chair', + 3: 'sleeping', + 4: 'sitting on a low chair', + 5: 'sitting on a medium chair', + 6: 'sitting on a high chair', + 7: 'dead', + 8: 'kneeling', + 9: 'submerged' +}; + +var g_quest_states = { + 0: 'not yet seen', + 1: 'completed', + 3: 'accepted', + 5: 'failed', + 6: 'been rewarded', +}; + +var g_condition_sources = { + 0: [['player', null], ''], // CND_SRC_NONE + 1: [['player', null], 'If the conditions are met, [item=$2] can be dropped by [npc=$1].'], // CND_SRC_CREATURE_LOOT_TEMPLATE + 2: [['player', null], 'If the conditions are met, [item=$2] can be found when disenchanting [item=$1].'], // CND_SRC_DISENCHANT_LOOT_TEMPLATE + 3: [['player', null], 'If the conditions are met, fishing in [zone=$1] can yield [item=$2].'], // CND_SRC_FISHING_LOOT_TEMPLATE + 4: [['player', null], 'If the conditions are met, [item=$2] can be found in [object=$1].'], // CND_SRC_GAMEOBJECT_LOOT_TEMPLATE + 5: [['player', null], 'If the conditions are met, [item=$2] can be found in [item=$1].'], // CND_SRC_ITEM_LOOT_TEMPLATE + 6: [['player', null], 'If the conditions are met, [item=$2] can be attached to the mail from [quest=$1].'], // CND_SRC_MAIL_LOOT_TEMPLATE + 7: [['player', null], 'If the conditions are met, [item=$2] can be milled from [item=$1].'], // CND_SRC_MILLING_LOOT_TEMPLATE + 8: [['player', null], 'If the conditions are met, [item=$2] can be picked from [npc=$1].'], // CND_SRC_PICKPOCKETING_LOOT_TEMPLATE + 9: [['player', null], 'If the conditions are met, [item=$2] can be prospected from [item=$1].'], // CND_SRC_PROSPECTING_LOOT_TEMPLATE + 10: [['player', null], 'If the conditions are met, [item=$2] will be referenced in template #$1.'], // CND_SRC_REFERENCE_LOOT_TEMPLATE + 11: [['player', null], 'If the conditions are met, [item=$2] can be gathered from [npc=$1].'], // CND_SRC_SKINNING_LOOT_TEMPLATE + 12: [['player', null], 'If the conditions are met, casting [spell=$1] may also create [item=$2].'], // CND_SRC_SPELL_LOOT_TEMPLATE + 13: [['target', 'caster'], 'Only a $T%:spell%; matching the conditions can be affected by [spell=$2].'], // CND_SRC_SPELL_IMPLICIT_TARGET + 14: [['player', 'entity'], 'Display Gossip text #$2 from menu #$1, if the conditions on the $T%:%; are met.'], // CND_SRC_GOSSIP_MENU + 15: [['player', 'entity'], 'Display Gossip option #$2 from menu #$1, if the conditions on the $T%:%; are met.'], // CND_SRC_GOSSIP_MENU_OPTION + 16: [['player', 'creature'], '[npc=$2] can be used as a vehicle, if $Tthe %s:its; conditions are met.'], // CND_SRC_CREATURE_TEMPLATE_VEHICLE + 17: [['caster', 'target'], '[spell=$2] can only be cast, if the $Tspell%s:%s; conditions are met.'], // CND_SRC_SPELL + 18: [['player', 'creature'], 'If the $T%s:%s; conditions are met, [npc=$1] casts [spell=$2] if clicked on.'], // CND_SRC_SPELL_CLICK_EVENT + 19: [['player', null], 'The Player can accept [quest=$2], if the condition is met.'], // CND_SRC_QUEST_ACCEPT + 20: [['player', null], 'A [icon name=quest_startend] [/icon] will be shown for [quest=$2], if the condition is met.'], // CND_SRC_QUEST_SHOW_MARK + 21: [['player', 'creature'], 'If the $T%s:%s; conditions are met, vehicle [npc=$1] has [spell=$2] available.'], // CND_SRC_VEHICLE_SPELL + 22: [['invoker', 'entity'], 'If the conditions for the $T%:%; are met, the AI may perform additional actions.'], // CND_SRC_SMART_EVENT (no, i'm not going to untangle this!) + 23: [['player', 'creature'], 'If the conditions for the $T%:%; are met, [npc=$1] will have [item=$2] for sale.'], // CND_SRC_NPC_VENDOR + 24: [['caster', 'target'], 'If the conditions for the $Tspell%:%; are met, the [spell=$2] is allowed to proc.'], // CND_SRC_SPELL_PROC + 30: [['player', null], 'If the conditions are met, [url=?areatrigger=$2]Areatrigger #$2[/url] is allowed to trigger.'] // CND_SRC_AREATRIGGER_CLIENT_TRIGGERED }; var g_conditions = { - 1: 'The Player $has:does not have; an aura of $1', - 2: 'The Player $owns: does not own; $1', - 3: 'The Player $has:does not have; $1 equipped', - 4: 'The Player is$: not; in $1', // also used by 22, 23 - 5: 'The Player\'s standing with $1 is$: not; $2', - 6: 'The Player is$: not; $1', - 7: 'The Player $knows: does not know; $1', - 8: 'The Player has$: not; finished $1', - 9: 'The Player has$: not; accepted $1', - 10: 'The Player is$: not; $1', - 11: 'WorldState #$1 is$: not; $2', - 12: '$1 must$: not; be active', - 13: 'The instance $has:does not have; a certain state', // nyi - 14: 'The Player has $never:; interacted with $1', - 15: 'The Player is$: not; a $1', // also used by 16 - 17: 'The Player has$: not; achieved $1', - 18: 'The Player has$: not; obtained $1', - 20: 'The Player\'s gender is$: not; [span class=icon-$2]$1[/span]', - 21: 'The target $has:does not have; a certain state', // nyi - 24: '', // not used - 25: 'The Player $knows: does not know; $1', - 26: 'The Creature is$: not; in phase $1', - 27: 'The target\'s level is$: not; $2 $1', - 28: 'The Player has$: not; completed $1', - 29: 'The Player is$: not; within $2yd of $1', // also used by 30 - 31: 'Casters\'s target is$: not; $1', // also used by 32 - 33: 'The Player $has:does not have; a certain relation to the target', // nyi - 34: 'The target $has:does not have; a certain reaction to the Player', // nyi - 35: 'The target is$: not; $2 $1yd away', - 36: 'The target is$: not; alive', - 37: 'The target\'s health is$: not; $2 $1', - 38: 'The target\'s health is$: not; $2 $1%' + 0: 'Always $Ntrue:false;', + 1: 'The target $Nhas:does not have; an aura of [spell=$1]', + 2: 'The Player $Nhas:does not have; $2 [item=$1] in their inventory$C$3 or bank:;', + 3: 'The Player $Nhas:does not have; [item=$1] equipped', + 4: 'The Player is$N: not; in [zone=$1]', + 5: 'The Player\'s standing with [faction=$1] is$N: not; $2', + 6: 'The Player is$N: not; a member of the $1', + 7: 'The Player is$N: not; proficient in [skill=$1]$C$2 (min. $2):;', + 8: 'The Player was$N: not; rewarded [quest=$1]', + 9: 'The Player has$N: not; accepted [quest=$1]', + 10: 'The Player is$N: not; $1', + 11: 'WorldState #$1 is$N: not; $2', + 12: '[event=$1] must$N: not; be active', + 13: 'The instance\'s $3 at index #$1 is$N: not; equal to "$2"', + 14: 'The Player has $Nnever:; interacted with [quest=$1]', + 15: 'The Player is$N: not; a $1', + 16: 'The Player is$N: not; a $1', + 17: 'The Player has$N: not; achieved [achievement=$1]', + 18: 'The Player has$N: not; obtained [title=$1]', + 19: 'The entity\'s SpawnMask is$N: not; equal to "$1"', + 20: 'The Player\'s gender is$N: not; $1', + 21: 'The unit\'s state is$N: not; $1', + 22: 'The target is$N: not; in $1', + 23: 'The target is$N: not; in [zone=$1]', + 24: 'The creature is$N: not; a $1', + 25: 'The Player $Nknows: does not know; [spell=$1]', + 26: 'The entity is$N: not; in phase $1', + 27: 'The target\'s level is$N: not; $2 $1', + 28: 'The Player has$N: not; completed [quest=$1]', + 29: 'The target is$N: not; within $2yd of $C$3deceased:alive; [npc=$1]', + 30: 'The target is$N: not; within $2yd of [object=$1]', + 31: 'The entity is$N: not; $C$2: a; $1$C$3 (GUID $3):;', + 32: 'The entity is$N: not; a $1', + 33: '$1 $2', // see g_relation_types + 34: 'The unit is$N: not; $2 to $1', + 35: 'The distance between unit and $1 is$N: not; $3 $2yd', + 36: 'The unit is$N: not; alive', + 37: 'The unit\'s health is$N: not; $2 $1 points', + 38: 'The unit\'s health is$N: not; $2 $1%', + 39: '[achievement=$1] $Nwas:is yet to be; achieved on this realm', + 40: 'The unit is$N: not; swimming', + 42: 'The creature is$N: not; $1', + 43: 'The Player has$N: not yet; done [quest=$1] for the day', + 44: 'The unit is$N: not; charmed', + 45: 'The Player $Nhas:doesn\'t have; an active $C$1hunter:summoned; pet', + 46: 'The Player is$N: not; riding a taxi', + 47: 'The Player has$N: not; $2 [quest=$1]', + 48: 'The Player has$N: not; collected $3 towards objective #$2 of [quest=$1]', + 49: 'The current map difficulty is #$1', + 50: 'The Player $C$1$Ncan:can\'t; be:is$N: not;; a Gamemaster' }; + /* end aowow custom */ var LANG = { @@ -4890,6 +4981,11 @@ var LANG = { /* AoWoW: start custom */ + tab_conditions: 'Conditions', + tab_condition_for: 'Condition for', + cnd_either: 'Either', + cnd_or: 'Or', + // Guide (wasn't localized at the time of capture) myguides: 'My Guides', listguides: 'List of guides', @@ -4912,7 +5008,7 @@ var LANG = { // Conditions note_condition: 'Every one of these conditions must be met to satisfy the requirement.', - note_condition_group: 'Any one of these groups must be met in full to satisfy the requirement.', + note_condition_group: 'One or more of these groups must be met entirely to satisfy the requirement.', // Aura Stack Rules asr_behaviour: 'Behaviour', diff --git a/static/js/locale_eses.js b/static/js/locale_eses.js index 582140d6..e89538ce 100644 --- a/static/js/locale_eses.js +++ b/static/js/locale_eses.js @@ -2407,67 +2407,158 @@ var g_world_object_types = { 7: 'Cadaver de Jugador' }; -var g_condition_types = { - 1: ['Looting', 'Si las condiciones se cumplen, este objeto puede ser arrojado por [npc=$1].'], // CND_SRC_CREATURE_LOOT_TEMPLATE - 2: ['Disenchanting', 'Si las condiciones se cumplen, este objeto puede ser encontrado al momento de desencantar [item=$1].'], // CND_SRC_DISENCHANT_LOOT_TEMPLATE - 3: ['Fishing', 'Si las condiciones se cumplen, pescando en [zone=$1] puede obtener el objeto'], // CND_SRC_FISHING_LOOT_TEMPLATE - 4: ['Object Opening', 'Si las condiciones se cumplen, este objeto puede ser encontrado en [object=$1].'], // CND_SRC_GAMEOBJECT_LOOT_TEMPLATE - 5: ['Item Opening', 'Si las condiciones se cumplen, este objeto puede ser encontrado en [item=$1].'], // CND_SRC_ITEM_LOOT_TEMPLATE - 6: ['Mail Attachm.', 'Si las condiciones se cumplen, este objeto puede adjuntado a este correo.'], // CND_SRC_MAIL_LOOT_TEMPLATE - 7: ['Milling', 'Si las condiciones se cumplen, este objeto puede ser molido de [item=$1].'], // CND_SRC_MILLING_LOOT_TEMPLATE - 8: ['Pickpocketing', 'Si las condiciones se cumplen, este objeto puede ser tomado de [npc=$1].'], // CND_SRC_PICKPOCKETING_LOOT_TEMPLATE - 9: ['Prospecting', 'Si las condiciones se cumplen, este objeto puede ser prospectado de [item=$1].'], // CND_SRC_PROSPECTING_LOOT_TEMPLATE - 10: ['Ref. Looting', ''], // CND_SRC_REFERENCE_LOOT_TEMPLATE - 11: ['Skinning', 'Si las condiciones se cumplen, este objeto puede ser desollado por [npc=$1].'], // CND_SRC_SKINNING_LOOT_TEMPLATE - 12: ['Crafting', 'Si las condiciones se cumplen, al lanzar [spell=$1] tambien puede crear este objeto.'], // CND_SRC_SPELL_LOOT_TEMPLATE - 13: ['Auto Target', 'Solo los blancos que cumplan las condiciones, pueden ser afectados por el hechizo.'], // CND_SRC_SPELL_IMPLICIT_TARGET - 14: ['Gossip', 'Muestra el texto relacionado del NPC [npc=$2], si las condiciones se cumplen.'], // CND_SRC_GOSSIP_MENU - 15: ['Gossip Menu', 'Muestra el menú relacionado, si las condiciones se cumplen.'], // CND_SRC_GOSSIP_MENU_OPTION - 16: ['Vehicle', 'Esta criatura puede ser usada como vehículo, si las condiciones se cumplen.'], // CND_SRC_CREATURE_TEMPLATE_VEHICLE - 17: ['Spell', 'Este hechizo solo puede ser lanzado, si las condiciones se cumplen.'], // CND_SRC_SPELL - 18: ['Spell Click', 'Si las condiciones se cumplen, [npc=$2] lanzará [spell=$1] si ha sido cliqueado.'], // CND_SRC_SPELL_CLICK_EVENT - 19: ['Quest Accept', 'El Jugador puede aceptar esta misión, si las condiciones se cumplen.'], // CND_SRC_QUEST_SHOW_MARK - 20: ['Quest Sign', 'El [icon name=quest_startend] [/icon] será mostrado para esta misión, si las condiciones se cumplen.'], // CND_SRC_QUEST_ACCEPT - 21: ['Vehicle Spell', 'Si las condiciones se cumplen, el vehículo [npc=$2] tendrá disponible [spell=$1].'], // CND_SRC_VEHICLE_SPELL - 22: ['SmartAI', 'Si las condiciones se cumplen, la criatura con IA puede realizar acciones adicionales.'], // CND_SRC_SMART_EVENT - 23: ['Vendor', 'Si las condiciones se cumplen, el vendedor tendrá este objeto disponible.'], // CND_SRC_NPC_VENDOR - 24: ['Spell Proc', 'Si las condiciones se cumplen, el hechizó tendrá permiso a tener chance en uso.'] // CND_SRC_SPELL_PROC +var g_instance_info = { + 0: 'Data', + 1: 'GUID', + 2: 'Boss State', + 3: 'Data64' +}; + +var g_unit_states = { + 0: 'Died', + 1: 'Melee attacking', + 2: 'Charmed', + 3: 'Stunned', + 4: 'Roaming', + 5: 'Chase', + 6: 'Focusing', + 7: 'Fleeing', + 8: 'In flight', + 9: 'Follow', + 10: 'Root', + 11: 'Confused', + 12: 'Distracted', + 13: 'Isolated', + 14: 'Attack player', + 15: 'Casting', + 16: 'Possessed', + 17: 'Charging', + 18: 'Jumping', + 19: 'Follow formation', + 20: 'Move', + 21: 'Rotating', + 22: 'Evade', + 23: 'Roaming move', + 24: 'Confused move', + 25: 'Fleeing move', + 26: 'Chase move', + 27: 'Follow move', + 28: 'Ignore pathfinding', + 29: 'Follow formation move' +}; + +var g_relation_types = { + 0: 'is$N: not; itself', + 1: 'is$N: not; in a group with $3', + 2: 'is$N: not; in a raid or party with $3', + 3: 'is$N: not; owned by $3', + 4: 'is$N: not; a passenger of $3', + 5: 'was$N: not; summoned by $3' +}; + +var g_stand_states = { + 0: 'standing', + 1: 'sitting', + 2: 'sitting on a chair', + 3: 'sleeping', + 4: 'sitting on a low chair', + 5: 'sitting on a medium chair', + 6: 'sitting on a high chair', + 7: 'dead', + 8: 'kneeling', + 9: 'submerged' +}; + +var g_quest_states = { + 0: 'not yet seen', + 1: 'completed', + 3: 'taken', + 5: 'failed', + 6: 'been rewarded', +}; + +var g_condition_sources = { + 0: [['player', null], ''], + 1: [['player', null], 'If the conditions are met, [item=$2] can be dropped by [npc=$1].'], // 'Si las condiciones se cumplen, este objeto puede ser arrojado por [npc=$1].' + 2: [['player', null], 'If the conditions are met, [item=$2] can be found when disenchanting [item=$1].'], // 'Si las condiciones se cumplen, este objeto puede ser encontrado al momento de desencantar [item=$1].' + 3: [['player', null], 'If the conditions are met, fishing in [zone=$1] can yield [item=$2].'], // 'Si las condiciones se cumplen, pescando en [zone=$1] puede obtener el objeto' + 4: [['player', null], 'If the conditions are met, [item=$2] can be found in [object=$1].'], // 'Si las condiciones se cumplen, este objeto puede ser encontrado en [object=$1].' + 5: [['player', null], 'If the conditions are met, [item=$2] can be found in [item=$1].'], // 'Si las condiciones se cumplen, este objeto puede ser encontrado en [item=$1].' + 6: [['player', null], 'If the conditions are met, [item=$2] can be attached to the mail from [quest=$1].'], // 'Si las condiciones se cumplen, este objeto puede adjuntado a este correo.' + 7: [['player', null], 'If the conditions are met, [item=$2] can be milled from [item=$1].'], // 'Si las condiciones se cumplen, este objeto puede ser molido de [item=$1].' + 8: [['player', null], 'If the conditions are met, [item=$2] can be picked from [npc=$1].'], // 'Si las condiciones se cumplen, este objeto puede ser tomado de [npc=$1].' + 9: [['player', null], 'If the conditions are met, [item=$2] can be prospected from [item=$1].'], // 'Si las condiciones se cumplen, este objeto puede ser prospectado de [item=$1].' + 10: [['player', null], 'If the conditions are met, [item=$2] will be referenced in template #$1.'], + 11: [['player', null], 'If the conditions are met, [item=$2] can be gathered from [npc=$1].'], // 'Si las condiciones se cumplen, este objeto puede ser desollado por [npc=$1].' + 12: [['player', null], 'If the conditions are met, casting [spell=$1] may also create [item=$2].'], // 'Si las condiciones se cumplen, al lanzar [spell=$1] tambien puede crear este objeto.' + 13: [['target', 'caster'], 'Only a $T%:spell%; matching the conditions can be affected by [spell=$2].'], // 'Solo los blancos que cumplan las condiciones, pueden ser afectados por el hechizo.' + 14: [['player', 'entity'], 'Display Gossip text #$2 from menu #$1, if the conditions on the $T%:%; are met.'], // 'Muestra el texto relacionado del NPC [npc=$2], si las condiciones se cumplen.' + 15: [['player', 'entity'], 'Display Gossip option #$2 from menu #$1, if the conditions on the $T%:%; are met.'], // 'Muestra el menú relacionado, si las condiciones se cumplen.' + 16: [['player', 'creature'], '[npc=$2] can be used as a vehicle, if $Tthe %s:its; conditions are met.'], // 'Esta criatura puede ser usada como vehículo, si las condiciones se cumplen.' + 17: [['caster', 'target'], '[spell=$2] can only be cast, if the $Tspell%s:%s; conditions are met.'], // 'Este hechizo solo puede ser lanzado, si las condiciones se cumplen.' + 18: [['player', 'creature'], 'If the $T%s:%s; conditions are met, [npc=$1] casts [spell=$2] if clicked on.'], // 'Si las condiciones se cumplen, [npc=$2] lanzará [spell=$1] si ha sido cliqueado.' + 19: [['player', null], 'The Player can accept [quest=$2], if the condition is met.'], // 'El Jugador puede aceptar esta misión, si las condiciones se cumplen.' + 20: [['player', null], 'A [icon name=quest_startend] [/icon] will be shown for [quest=$2], if the condition is met.'], // 'El [icon name=quest_startend] [/icon] será mostrado para esta misión, si las condiciones se cumplen.' + 21: [['player', 'creature'], 'If the $T%s:%s; conditions are met, vehicle [npc=$1] has [spell=$2] available.'], // 'Si las condiciones se cumplen, el vehículo [npc=$2] tendrá disponible [spell=$1].' + 22: [['invoker', 'entity'], 'If the conditions for the $T%:%; are met, the AI may perform additional actions.'], // 'Si las condiciones se cumplen, la criatura con IA puede realizar acciones adicionales.' + 23: [['player', 'creature'], 'If the conditions for the $T%:%; are met, [npc=$1] will have [item=$2] for sale.'], // 'Si las condiciones se cumplen, el vendedor tendrá este objeto disponible.' + 24: [['caster', 'target'], 'If the conditions for the $Tspell%:%; are met, the [spell=$2] is allowed to proc.'], // 'Si las condiciones se cumplen, el hechizó tendrá permiso a tener chance en uso.' + 30: [['player', null], 'If the conditions are met, [url=?areatrigger=$2]Areatrigger #$2[/url] is allowed to trigger.'] }; var g_conditions = { - 1: 'El Jugador $tiene:no tiene; un aura de $1', - 2: 'El Jugador $posee: no posee; $1', - 3: 'El Jugador $tiene:no tiene ; $1 equipado', - 4: 'El Jugador es$: no; en $1', // also used by 22, 23 - 5: 'El/Los Jugador/es que tienen $1 es$: no; $2', - 6: 'El Jugador es$: no; $1', - 7: 'El Jugador $sabe: no sabe; $1', - 8: 'El Jugador tiene$: no; finalizado $1', - 9: 'El Jugador tiene$: no; aceptado $1', - 10: 'El Jugador es$: no; $1', - 11: 'WorldState #$1 es$: no; $2', - 12: '$1 debe$: no; estar activo', - 13: 'La instancia $debe:no debe; en cierto estado', // nyi - 14: 'El Jugador tiene $nunca:; ha interactuado con $1', - 15: 'El Jugador es$: no; un $1', // also used by 16 - 17: 'El Jugador tiene$: no; alcanzado $1', - 18: 'El Jugador tiene$: no; obtenido $1', - 20: 'El/Los genero/s del/los Jugador/es es$: no; [span class=icon-$2]$1[/span]', - 21: 'El objetivo $tiene:no tiene; un cierto estado', // nyi - 24: '', // not used - 25: 'El Jugador $sabe: no sabe; $1', - 26: 'La criatura es$: no; en fase $1', - 27: 'El/Los nivel/es del/los objetivo/s es/son$: no; $2 $1', - 28: 'El Jugador tiene$: no; completado $1', - 29: 'El Jugador esta$: no; entre $2yardas de $1', // also used by 30 - 31: 'El/los objetivo/s del lanzador esta$: no; $1', // also used by 32 - 33: 'El Jugador $tiene:no tiene; cierta relación con el objetivo', // nyi - 34: 'El objetivo $tiene:no tiene; cierta reacción al Jugador', // nyi - 35: 'El objetivo esta$: no; $2 $1yarda cerca', - 36: 'El objetivo esta$: no; vivo', - 37: 'La salud del objetivo/s esta$: no; $2 $1', - 38: 'La salud del objetivo/s esta$: no; $2 $1%' + 0: 'Always $Ntrue:false;', + 1: 'The target $Nhas:does not have; an aura of [spell=$1]', // 'El Jugador $tiene:no tiene; un aura de $1' + 2: 'The Player $Nhas:does not have; $2 [item=$1] in their inventory$C$3 or bank:;', // 'El Jugador $posee: no posee; $1', + 3: 'The Player $Nhas:does not have; [item=$1] equipped', // 'El Jugador $tiene:no tiene ; $1 equipado', + 4: 'The Player is$N: not; in [zone=$1]', // 'El Jugador es$: no; en $1', + 5: 'The Player\'s standing with [faction=$1] is$N: not; $2', // 'El/Los Jugador/es que tienen $1 es$: no; $2', + 6: 'The Player is$N: not; a member of the $1', // 'El Jugador es$: no; $1', + 7: 'The Player is$N: not; proficient in [skill=$1]$C$2 (min. $2):;', // 'El Jugador $sabe: no sabe; $1', + 8: 'The Player was$N: not; rewarded [quest=$1]', // 'El Jugador tiene$: no; finalizado $1', + 9: 'The Player has$N: not; accepted [quest=$1]', // 'El Jugador tiene$: no; aceptado $1', + 10: 'The Player is$N: not; $1', // 'El Jugador es$: no; $1', + 11: 'WorldState #$1 is$N: not; $2', // 'WorldState #$1 es$: no; $2', + 12: '[event=$1] must$N: not; be active', // '$1 debe$: no; estar activo', + 13: 'The instance\'s $3 at index #$1 is$N: not; equal to "$2"', // 'La instancia $debe:no debe; en cierto estado', // nyi + 14: 'The Player has $Nnever:; interacted with [quest=$1]', // 'El Jugador tiene $nunca:; ha interactuado con $1', + 15: 'The Player is$N: not; a $1', // 'El Jugador es$: no; un $1', + 16: 'The Player is$N: not; a $1', + 17: 'The Player has$N: not; achieved [achievement=$1]', // 'El Jugador tiene$: no; alcanzado $1', + 18: 'The Player has$N: not; obtained [title=$1]', // 'El Jugador tiene$: no; obtenido $1', + 19: 'The entity\'s SpawnMask is$N: not; equal to "$1"', + 20: 'The Player\'s gender is$N: not; $1', // 'El/Los genero/s del/los Jugador/es es$: no; [span class=icon-$2]$1[/span]', + 21: 'The unit\'s state is$N: not; $1', // 'El objetivo $tiene:no tiene; un cierto estado', + 22: 'The target is$N: not; in $1', + 23: 'The target is$N: not; in [zone=$1]', + 24: 'The creature is$N: not; a $1', + 25: 'The Player $Nknows: does not know; [spell=$1]', // 'El Jugador $sabe: no sabe; $1', + 26: 'The entity is$N: not; in phase $1', // 'La criatura es$: no; en fase $1', + 27: 'The target\'s level is$N: not; $2 $1', // 'El/Los nivel/es del/los objetivo/s es/son$: no; $2 $1', + 28: 'The Player has$N: not; completed [quest=$1]', // 'El Jugador tiene$: no; completado $1', + 29: 'The target is$N: not; within $2yd of $C$3deceased:alive; [npc=$1]', // 'El Jugador esta$: no; entre $2yardas de $1', + 30: 'The target is$N: not; within $2yd of [object=$1]', + 31: 'The entity is$N: not; $C$2: a; $1$C$3 (GUID $3):;', // 'El/los objetivo/s del lanzador esta$: no; $1', + 32: 'The entity is$N: not; a $1', + 33: '$1 $2', // 'El Jugador $tiene:no tiene; cierta relación con el objetivo', + 34: 'The unit is$N: not; $2 to $1', // 'El objetivo $tiene:no tiene; cierta reacción al Jugador', + 35: 'The distance between unit and $1 is$N: not; $3 $2yd', // 'El objetivo esta$: no; $2 $1yarda cerca', + 36: 'The unit is$N: not; alive', // 'El objetivo esta$: no; vivo', + 37: 'The unit\'s health is$N: not; $2 $1 points', // 'La salud del objetivo/s esta$: no; $2 $1', + 38: 'The unit\'s health is$N: not; $2 $1%', // 'La salud del objetivo/s esta$: no; $2 $1%' + 39: '[achievement=$1] $Nwas:is yet to be; achieved on this realm', + 40: 'The unit is$N: not; swimming', + 42: 'The creature is$N: not; $1', + 43: 'The Player has$N: not yet; done [quest=$1] for the day', + 44: 'The unit is$N: not; charmed', + 45: 'The Player $Nhas:doesn\'t have; an active $C$1hunter:summoned; pet', + 46: 'The Player is$N: not; riding a taxi', + 47: 'The Player has$N: not; $2 [quest=$1]', + 48: 'The Player has$N: not; collected $3 towards objective #$2 of [quest=$1]', + 49: 'The current map difficulty is #$1', + 50: 'The Player $C$1$Ncan:can\'t; be:is$N: not;; a Gamemaster' }; + /* end aowow custom */ var LANG = { @@ -4844,6 +4935,11 @@ var LANG = { /* AoWoW: start custom */ + tab_conditions: '[Conditions]', + tab_condition_for: '[Condition for]', + cnd_either: '[Either]', + cnd_or: '[Or]', + // Guide myguides: 'Mis Guías', listguides: '[List of guides]', diff --git a/static/js/locale_frfr.js b/static/js/locale_frfr.js index fdc29fed..2de41571 100644 --- a/static/js/locale_frfr.js +++ b/static/js/locale_frfr.js @@ -2407,67 +2407,158 @@ var g_world_object_types = { 7: 'Player Corpse' }; -var g_condition_types = { - 1: ['Looting', 'If the conditions are met, this item can be dropped by [npc=$1].'], // CND_SRC_CREATURE_LOOT_TEMPLATE - 2: ['Disenchanting', 'If the conditions are met, this item can be found when disenchanting [item=$1].'], // CND_SRC_DISENCHANT_LOOT_TEMPLATE - 3: ['Fishing', 'If the conditions are met, fishing in [zone=$1] can yield this item.'], // CND_SRC_FISHING_LOOT_TEMPLATE - 4: ['Object Opening', 'If the conditions are met, this item can be found in [object=$1].'], // CND_SRC_GAMEOBJECT_LOOT_TEMPLATE - 5: ['Item Opening', 'If the conditions are met, this item can be found in [item=$1].'], // CND_SRC_ITEM_LOOT_TEMPLATE - 6: ['Mail Attachm.', 'If the conditions are met, this item can be attached to this mail.'], // CND_SRC_MAIL_LOOT_TEMPLATE - 7: ['Milling', 'If the conditions are met, this item can be milled from [item=$1].'], // CND_SRC_MILLING_LOOT_TEMPLATE - 8: ['Pickpocketing', 'If the conditions are met, this item can be picked from [npc=$1].'], // CND_SRC_PICKPOCKETING_LOOT_TEMPLATE - 9: ['Prospecting', 'If the conditions are met, this item can be prospected from [item=$1].'], // CND_SRC_PROSPECTING_LOOT_TEMPLATE - 10: ['Ref. Looting', ''], // CND_SRC_REFERENCE_LOOT_TEMPLATE - 11: ['Skinning', 'If the conditions are met, this item can be skinned from [npc=$1].'], // CND_SRC_SKINNING_LOOT_TEMPLATE - 12: ['Crafting', 'If the conditions are met, casting [spell=$1] may also create this item.'], // CND_SRC_SPELL_LOOT_TEMPLATE - 13: ['Auto Target', 'Only targets matching the conditions can be affected by the spell.'], // CND_SRC_SPELL_IMPLICIT_TARGET - 14: ['Gossip', 'Display the related Gossip entry on [npc=$2], if the conditions are met.'], // CND_SRC_GOSSIP_MENU - 15: ['Gossip Menu', 'Display the related Gossip menu, if the conditions are met.'], // CND_SRC_GOSSIP_MENU_OPTION - 16: ['Vehicle', 'This Creature can be used as a vehicle, if the conditions are met.'], // CND_SRC_CREATURE_TEMPLATE_VEHICLE - 17: ['Spell', 'This Spell can only be cast, if the conditions are met.'], // CND_SRC_SPELL - 18: ['Spell Click', 'If the conditions are met, [npc=$2] casts [spell=$1] if clicked on.'], // CND_SRC_SPELL_CLICK_EVENT - 19: ['Quest Accept', 'The Player can accept this quest, if the condition is met.'], // CND_SRC_QUEST_SHOW_MARK - 20: ['Quest Sign', 'A [icon name=quest_startend] [/icon] will be shown for this quest, if the condition is met.'], // CND_SRC_QUEST_ACCEPT - 21: ['Vehicle Spell', 'If the conditions are met, vehicle [npc=$2] has [spell=$1] available.'], // CND_SRC_VEHICLE_SPELL - 22: ['SmartAI', 'If the conditions are met, the creatures AI may perform additional actions.'], // CND_SRC_SMART_EVENT - 23: ['Vendor', 'If the conditions are met, the vendor will have this item available.'], // CND_SRC_NPC_VENDOR - 24: ['Spell Proc', 'If the conditions are met, the spell is allowed to proc.'] // CND_SRC_SPELL_PROC +var g_instance_info = { + 0: 'Data', + 1: 'GUID', + 2: 'Boss State', + 3: 'Data64' +}; + +var g_unit_states = { + 0: 'Died', + 1: 'Melee attacking', + 2: 'Charmed', + 3: 'Stunned', + 4: 'Roaming', + 5: 'Chase', + 6: 'Focusing', + 7: 'Fleeing', + 8: 'In flight', + 9: 'Follow', + 10: 'Root', + 11: 'Confused', + 12: 'Distracted', + 13: 'Isolated', + 14: 'Attack player', + 15: 'Casting', + 16: 'Possessed', + 17: 'Charging', + 18: 'Jumping', + 19: 'Follow formation', + 20: 'Move', + 21: 'Rotating', + 22: 'Evade', + 23: 'Roaming move', + 24: 'Confused move', + 25: 'Fleeing move', + 26: 'Chase move', + 27: 'Follow move', + 28: 'Ignore pathfinding', + 29: 'Follow formation move' +}; + +var g_relation_types = { + 0: 'is$N: not; itself', + 1: 'is$N: not; in a group with $3', + 2: 'is$N: not; in a raid or party with $3', + 3: 'is$N: not; owned by $3', + 4: 'is$N: not; a passenger of $3', + 5: 'was$N: not; summoned by $3' +}; + +var g_stand_states = { + 0: 'standing', + 1: 'sitting', + 2: 'sitting on a chair', + 3: 'sleeping', + 4: 'sitting on a low chair', + 5: 'sitting on a medium chair', + 6: 'sitting on a high chair', + 7: 'dead', + 8: 'kneeling', + 9: 'submerged' +}; + +var g_quest_states = { + 0: 'not yet seen', + 1: 'completed', + 3: 'taken', + 5: 'failed', + 6: 'been rewarded', +}; + +var g_condition_sources = { + 0: [['player', null], ''], + 1: [['player', null], 'If the conditions are met, [item=$2] can be dropped by [npc=$1].'], + 2: [['player', null], 'If the conditions are met, [item=$2] can be found when disenchanting [item=$1].'], + 3: [['player', null], 'If the conditions are met, fishing in [zone=$1] can yield [item=$2].'], + 4: [['player', null], 'If the conditions are met, [item=$2] can be found in [object=$1].'], + 5: [['player', null], 'If the conditions are met, [item=$2] can be found in [item=$1].'], + 6: [['player', null], 'If the conditions are met, [item=$2] can be attached to the mail from [quest=$1].'], + 7: [['player', null], 'If the conditions are met, [item=$2] can be milled from [item=$1].'], + 8: [['player', null], 'If the conditions are met, [item=$2] can be picked from [npc=$1].'], + 9: [['player', null], 'If the conditions are met, [item=$2] can be prospected from [item=$1].'], + 10: [['player', null], 'If the conditions are met, [item=$2] will be referenced in template #$1.'], + 11: [['player', null], 'If the conditions are met, [item=$2] can be gathered from [npc=$1].'], + 12: [['player', null], 'If the conditions are met, casting [spell=$1] may also create [item=$2].'], + 13: [['target', 'caster'], 'Only a $T%:spell%; matching the conditions can be affected by [spell=$2].'], + 14: [['player', 'entity'], 'Display Gossip text #$2 from menu #$1, if the conditions on the $T%:%; are met.'], + 15: [['player', 'entity'], 'Display Gossip option #$2 from menu #$1, if the conditions on the $T%:%; are met.'], + 16: [['player', 'creature'], '[npc=$2] can be used as a vehicle, if $Tthe %s:its; conditions are met.'], + 17: [['caster', 'target'], '[spell=$2] can only be cast, if the $Tspell%s:%s; conditions are met.'], + 18: [['player', 'creature'], 'If the $T%s:%s; conditions are met, [npc=$1] casts [spell=$2] if clicked on.'], + 19: [['player', null], 'The Player can accept [quest=$2], if the condition is met.'], + 20: [['player', null], 'A [icon name=quest_startend] [/icon] will be shown for [quest=$2], if the condition is met.'], + 21: [['player', 'creature'], 'If the $T%s:%s; conditions are met, vehicle [npc=$1] has [spell=$2] available.'], + 22: [['invoker', 'entity'], 'If the conditions for the $T%:%; are met, the AI may perform additional actions.'], + 23: [['player', 'creature'], 'If the conditions for the $T%:%; are met, [npc=$1] will have [item=$2] for sale.'], + 24: [['caster', 'target'], 'If the conditions for the $Tspell%:%; are met, the [spell=$2] is allowed to proc.'], + 30: [['player', null], 'If the conditions are met, [url=?areatrigger=$2]Areatrigger #$2[/url] is allowed to trigger.'] }; var g_conditions = { - 1: 'The Player $has:does not have; an aura of $1', - 2: 'The Player $owns: does not own; $1', - 3: 'The Player $has:does not have; $1 equipped', - 4: 'The Player is$: not; in $1', // also used by 22, 23 - 5: 'The Player\'s standing with $1 is$: not; $2', - 6: 'The Player is$: not; $1', - 7: 'The Player $knows: does not know; $1', - 8: 'The Player has$: not; finished $1', - 9: 'The Player has$: not; accepted $1', - 10: 'The Player is$: not; $1', - 11: 'WorldState #$1 is$: not; $2', - 12: '$1 must$: not; be active', - 13: 'The instance $has:does not have; a certain state', // nyi - 14: 'The Player has $never:; interacted with $1', - 15: 'The Player is$: not; a $1', // also used by 16 - 17: 'The Player has$: not; achieved $1', - 18: 'The Player has$: not; obtained $1', - 20: 'The Player\'s gender is$: not; [span class=icon-$2]$1[/span]', - 21: 'The target $has:does not have; a certain state', // nyi - 24: '', // not used - 25: 'The Player $knows: does not know; $1', - 26: 'The Creature is$: not; in phase $1', - 27: 'The target\'s level is$: not; $2 $1', - 28: 'The Player has$: not; completed $1', - 29: 'The Player is$: not; within $2yd of $1', // also used by 30 - 31: 'Casters\'s target is$: not; $1', // also used by 32 - 33: 'The Player $has:does not have; a certain relation to the target', // nyi - 34: 'The target $has:does not have; a certain reaction to the Player', // nyi - 35: 'The target is$: not; $2 $1yd away', - 36: 'The target is$: not; alive', - 37: 'The target\'s health is$: not; $2 $1', - 37: 'The target\'s health is$: not; $2 $1%' + 0: 'Always $Ntrue:false;', + 1: 'The target $Nhas:does not have; an aura of [spell=$1]', + 2: 'The Player $Nhas:does not have; $2 [item=$1] in their inventory$C$3 or bank:;', + 3: 'The Player $Nhas:does not have; [item=$1] equipped', + 4: 'The Player is$N: not; in [zone=$1]', + 5: 'The Player\'s standing with [faction=$1] is$N: not; $2', + 6: 'The Player is$N: not; a member of the $1', + 7: 'The Player is$N: not; proficient in [skill=$1]$C$2 (min. $2):;', + 8: 'The Player was$N: not; rewarded [quest=$1]', + 9: 'The Player has$N: not; accepted [quest=$1]', + 10: 'The Player is$N: not; $1', + 11: 'WorldState #$1 is$N: not; $2', + 12: '[event=$1] must$N: not; be active', + 13: 'The instance\'s $3 at index #$1 is$N: not; equal to "$2"', + 14: 'The Player has $Nnever:; interacted with [quest=$1]', + 15: 'The Player is$N: not; a $1', + 16: 'The Player is$N: not; a $1', + 17: 'The Player has$N: not; achieved [achievement=$1]', + 18: 'The Player has$N: not; obtained [title=$1]', + 19: 'The entity\'s SpawnMask is$N: not; equal to "$1"', + 20: 'The Player\'s gender is$N: not; $1', + 21: 'The unit\'s state is$N: not; $1', + 22: 'The target is$N: not; in $1', + 23: 'The target is$N: not; in [zone=$1]', + 24: 'The creature is$N: not; a $1', + 25: 'The Player $Nknows: does not know; [spell=$1]', + 26: 'The entity is$N: not; in phase $1', + 27: 'The target\'s level is$N: not; $2 $1', + 28: 'The Player has$N: not; completed [quest=$1]', + 29: 'The target is$N: not; within $2yd of $C$3deceased:alive; [npc=$1]', + 30: 'The target is$N: not; within $2yd of [object=$1]', + 31: 'The entity is$N: not; $C$2: a; $1$C$3 (GUID $3):;', + 32: 'The entity is$N: not; a $1', + 33: '$1 $2', + 34: 'The unit is$N: not; $2 to $1', + 35: 'The distance between unit and $1 is$N: not; $3 $2yd', + 36: 'The unit is$N: not; alive', + 37: 'The unit\'s health is$N: not; $2 $1 points', + 38: 'The unit\'s health is$N: not; $2 $1%', + 39: '[achievement=$1] $Nwas:is yet to be; achieved on this realm', + 40: 'The unit is$N: not; swimming', + 42: 'The creature is$N: not; $1', + 43: 'The Player has$N: not yet; done [quest=$1] for the day', + 44: 'The unit is$N: not; charmed', + 45: 'The Player $Nhas:doesn\'t have; an active $C$1hunter:summoned; pet', + 46: 'The Player is$N: not; riding a taxi', + 47: 'The Player has$N: not; $2 [quest=$1]', + 48: 'The Player has$N: not; collected $3 towards objective #$2 of [quest=$1]', + 49: 'The current map difficulty is #$1', + 50: 'The Player $C$1$Ncan:can\'t; be:is$N: not;; a Gamemaster' }; + /* end aowow custom */ var LANG = { @@ -4844,6 +4935,11 @@ var LANG = { /* AoWoW: start custom */ + tab_conditions: '[Conditions]', + tab_condition_for: '[Condition for]', + cnd_either: '[Either]', + cnd_or: '[Or]', + // Guide myguides: 'Mes guides', listguides: '[List of guides]', diff --git a/static/js/locale_ruru.js b/static/js/locale_ruru.js index cdf325d7..6e1e303a 100644 --- a/static/js/locale_ruru.js +++ b/static/js/locale_ruru.js @@ -2407,67 +2407,158 @@ var g_world_object_types = { 7: 'Player Corpse' }; -var g_condition_types = { - 1: ['Looting', 'If the conditions are met, this item can be dropped by [npc=$1].'], // CND_SRC_CREATURE_LOOT_TEMPLATE - 2: ['Disenchanting', 'If the conditions are met, this item can be found when disenchanting [item=$1].'], // CND_SRC_DISENCHANT_LOOT_TEMPLATE - 3: ['Fishing', 'If the conditions are met, fishing in [zone=$1] can yield this item.'], // CND_SRC_FISHING_LOOT_TEMPLATE - 4: ['Object Opening', 'If the conditions are met, this item can be found in [object=$1].'], // CND_SRC_GAMEOBJECT_LOOT_TEMPLATE - 5: ['Item Opening', 'If the conditions are met, this item can be found in [item=$1].'], // CND_SRC_ITEM_LOOT_TEMPLATE - 6: ['Mail Attachm.', 'If the conditions are met, this item can be attached to this mail.'], // CND_SRC_MAIL_LOOT_TEMPLATE - 7: ['Milling', 'If the conditions are met, this item can be milled from [item=$1].'], // CND_SRC_MILLING_LOOT_TEMPLATE - 8: ['Pickpocketing', 'If the conditions are met, this item can be picked from [npc=$1].'], // CND_SRC_PICKPOCKETING_LOOT_TEMPLATE - 9: ['Prospecting', 'If the conditions are met, this item can be prospected from [item=$1].'], // CND_SRC_PROSPECTING_LOOT_TEMPLATE - 10: ['Ref. Looting', ''], // CND_SRC_REFERENCE_LOOT_TEMPLATE - 11: ['Skinning', 'If the conditions are met, this item can be skinned from [npc=$1].'], // CND_SRC_SKINNING_LOOT_TEMPLATE - 12: ['Crafting', 'If the conditions are met, casting [spell=$1] may also create this item.'], // CND_SRC_SPELL_LOOT_TEMPLATE - 13: ['Auto Target', 'Only targets matching the conditions can be affected by the spell.'], // CND_SRC_SPELL_IMPLICIT_TARGET - 14: ['Gossip', 'Display the related Gossip entry on [npc=$2], if the conditions are met.'], // CND_SRC_GOSSIP_MENU - 15: ['Gossip Menu', 'Display the related Gossip menu, if the conditions are met.'], // CND_SRC_GOSSIP_MENU_OPTION - 16: ['Vehicle', 'This Creature can be used as a vehicle, if the conditions are met.'], // CND_SRC_CREATURE_TEMPLATE_VEHICLE - 17: ['Spell', 'This Spell can only be cast, if the conditions are met.'], // CND_SRC_SPELL - 18: ['Spell Click', 'If the conditions are met, [npc=$2] casts [spell=$1] if clicked on.'], // CND_SRC_SPELL_CLICK_EVENT - 19: ['Quest Accept', 'The Player can accept this quest, if the condition is met.'], // CND_SRC_QUEST_SHOW_MARK - 20: ['Quest Sign', 'A [icon name=quest_startend] [/icon] will be shown for this quest, if the condition is met.'], // CND_SRC_QUEST_ACCEPT - 21: ['Vehicle Spell', 'If the conditions are met, vehicle [npc=$2] has [spell=$1] available.'], // CND_SRC_VEHICLE_SPELL - 22: ['SmartAI', 'If the conditions are met, the creatures AI may perform additional actions.'], // CND_SRC_SMART_EVENT - 23: ['Vendor', 'If the conditions are met, the vendor will have this item available.'], // CND_SRC_NPC_VENDOR - 24: ['Spell Proc', 'If the conditions are met, the spell is allowed to proc.'] // CND_SRC_SPELL_PROC +var g_instance_info = { + 0: 'Data', + 1: 'GUID', + 2: 'Boss State', + 3: 'Data64' +}; + +var g_unit_states = { + 0: 'Died', + 1: 'Melee attacking', + 2: 'Charmed', + 3: 'Stunned', + 4: 'Roaming', + 5: 'Chase', + 6: 'Focusing', + 7: 'Fleeing', + 8: 'In flight', + 9: 'Follow', + 10: 'Root', + 11: 'Confused', + 12: 'Distracted', + 13: 'Isolated', + 14: 'Attack player', + 15: 'Casting', + 16: 'Possessed', + 17: 'Charging', + 18: 'Jumping', + 19: 'Follow formation', + 20: 'Move', + 21: 'Rotating', + 22: 'Evade', + 23: 'Roaming move', + 24: 'Confused move', + 25: 'Fleeing move', + 26: 'Chase move', + 27: 'Follow move', + 28: 'Ignore pathfinding', + 29: 'Follow formation move' +}; + +var g_relation_types = { + 0: 'is$N: not; itself', + 1: 'is$N: not; in a group with $3', + 2: 'is$N: not; in a raid or party with $3', + 3: 'is$N: not; owned by $3', + 4: 'is$N: not; a passenger of $3', + 5: 'was$N: not; summoned by $3' +}; + +var g_stand_states = { + 0: 'standing', + 1: 'sitting', + 2: 'sitting on a chair', + 3: 'sleeping', + 4: 'sitting on a low chair', + 5: 'sitting on a medium chair', + 6: 'sitting on a high chair', + 7: 'dead', + 8: 'kneeling', + 9: 'submerged' +}; + +var g_quest_states = { + 0: 'not yet seen', + 1: 'completed', + 3: 'taken', + 5: 'failed', + 6: 'been rewarded', +}; + +var g_condition_sources = { + 0: [['player', null], ''], + 1: [['player', null], 'If the conditions are met, [item=$2] can be dropped by [npc=$1].'], + 2: [['player', null], 'If the conditions are met, [item=$2] can be found when disenchanting [item=$1].'], + 3: [['player', null], 'If the conditions are met, fishing in [zone=$1] can yield [item=$2].'], + 4: [['player', null], 'If the conditions are met, [item=$2] can be found in [object=$1].'], + 5: [['player', null], 'If the conditions are met, [item=$2] can be found in [item=$1].'], + 6: [['player', null], 'If the conditions are met, [item=$2] can be attached to the mail from [quest=$1].'], + 7: [['player', null], 'If the conditions are met, [item=$2] can be milled from [item=$1].'], + 8: [['player', null], 'If the conditions are met, [item=$2] can be picked from [npc=$1].'], + 9: [['player', null], 'If the conditions are met, [item=$2] can be prospected from [item=$1].'], + 10: [['player', null], 'If the conditions are met, [item=$2] will be referenced in template #$1.'], + 11: [['player', null], 'If the conditions are met, [item=$2] can be gathered from [npc=$1].'], + 12: [['player', null], 'If the conditions are met, casting [spell=$1] may also create [item=$2].'], + 13: [['target', 'caster'], 'Only a $T%:spell%; matching the conditions can be affected by [spell=$2].'], + 14: [['player', 'entity'], 'Display Gossip text #$2 from menu #$1, if the conditions on the $T%:%; are met.'], + 15: [['player', 'entity'], 'Display Gossip option #$2 from menu #$1, if the conditions on the $T%:%; are met.'], + 16: [['player', 'creature'], '[npc=$2] can be used as a vehicle, if $Tthe %s:its; conditions are met.'], + 17: [['caster', 'target'], '[spell=$2] can only be cast, if the $Tspell%s:%s; conditions are met.'], + 18: [['player', 'creature'], 'If the $T%s:%s; conditions are met, [npc=$1] casts [spell=$2] if clicked on.'], + 19: [['player', null], 'The Player can accept [quest=$2], if the condition is met.'], + 20: [['player', null], 'A [icon name=quest_startend] [/icon] will be shown for [quest=$2], if the condition is met.'], + 21: [['player', 'creature'], 'If the $T%s:%s; conditions are met, vehicle [npc=$1] has [spell=$2] available.'], + 22: [['invoker', 'entity'], 'If the conditions for the $T%:%; are met, the AI may perform additional actions.'], + 23: [['player', 'creature'], 'If the conditions for the $T%:%; are met, [npc=$1] will have [item=$2] for sale.'], + 24: [['caster', 'target'], 'If the conditions for the $Tspell%:%; are met, the [spell=$2] is allowed to proc.'], + 30: [['player', null], 'If the conditions are met, [url=?areatrigger=$2]Areatrigger #$2[/url] is allowed to trigger.'] }; var g_conditions = { - 1: 'The Player $has:does not have; an aura of $1', - 2: 'The Player $owns: does not own; $1', - 3: 'The Player $has:does not have; $1 equipped', - 4: 'The Player is$: not; in $1', // also used by 22, 23 - 5: 'The Player\'s standing with $1 is$: not; $2', - 6: 'The Player is$: not; $1', - 7: 'The Player $knows: does not know; $1', - 8: 'The Player has$: not; finished $1', - 9: 'The Player has$: not; accepted $1', - 10: 'The Player is$: not; $1', - 11: 'WorldState #$1 is$: not; $2', - 12: '$1 must$: not; be active', - 13: 'The instance $has:does not have; a certain state', // nyi - 14: 'The Player has $never:; interacted with $1', - 15: 'The Player is$: not; a $1', // also used by 16 - 17: 'The Player has$: not; achieved $1', - 18: 'The Player has$: not; obtained $1', - 20: 'The Player\'s gender is$: not; [span class=icon-$2]$1[/span]', - 21: 'The target $has:does not have; a certain state', // nyi - 24: '', // not used - 25: 'The Player $knows: does not know; $1', - 26: 'The Creature is$: not; in phase $1', - 27: 'The target\'s level is$: not; $2 $1', - 28: 'The Player has$: not; completed $1', - 29: 'The Player is$: not; within $2yd of $1', // also used by 30 - 31: 'Casters\'s target is$: not; $1', // also used by 32 - 33: 'The Player $has:does not have; a certain relation to the target', // nyi - 34: 'The target $has:does not have; a certain reaction to the Player', // nyi - 35: 'The target is$: not; $2 $1yd away', - 36: 'The target is$: not; alive', - 37: 'The target\'s health is$: not; $2 $1', - 38: 'The target\'s health is$: not; $2 $1%' + 0: 'Always $Ntrue:false;', + 1: 'The target $Nhas:does not have; an aura of [spell=$1]', + 2: 'The Player $Nhas:does not have; $2 [item=$1] in their inventory$C$3 or bank:;', + 3: 'The Player $Nhas:does not have; [item=$1] equipped', + 4: 'The Player is$N: not; in [zone=$1]', + 5: 'The Player\'s standing with [faction=$1] is$N: not; $2', + 6: 'The Player is$N: not; a member of the $1', + 7: 'The Player is$N: not; proficient in [skill=$1]$C$2 (min. $2):;', + 8: 'The Player was$N: not; rewarded [quest=$1]', + 9: 'The Player has$N: not; accepted [quest=$1]', + 10: 'The Player is$N: not; $1', + 11: 'WorldState #$1 is$N: not; $2', + 12: '[event=$1] must$N: not; be active', + 13: 'The instance\'s $3 at index #$1 is$N: not; equal to "$2"', + 14: 'The Player has $Nnever:; interacted with [quest=$1]', + 15: 'The Player is$N: not; a $1', + 16: 'The Player is$N: not; a $1', + 17: 'The Player has$N: not; achieved [achievement=$1]', + 18: 'The Player has$N: not; obtained [title=$1]', + 19: 'The entity\'s SpawnMask is$N: not; equal to "$1"', + 20: 'The Player\'s gender is$N: not; $1', + 21: 'The unit\'s state is$N: not; $1', + 22: 'The target is$N: not; in $1', + 23: 'The target is$N: not; in [zone=$1]', + 24: 'The creature is$N: not; a $1', + 25: 'The Player $Nknows: does not know; [spell=$1]', + 26: 'The entity is$N: not; in phase $1', + 27: 'The target\'s level is$N: not; $2 $1', + 28: 'The Player has$N: not; completed [quest=$1]', + 29: 'The target is$N: not; within $2yd of $C$3deceased:alive; [npc=$1]', + 30: 'The target is$N: not; within $2yd of [object=$1]', + 31: 'The entity is$N: not; $C$2: a; $1$C$3 (GUID $3):;', + 32: 'The entity is$N: not; a $1', + 33: '$1 $2', + 34: 'The unit is$N: not; $2 to $1', + 35: 'The distance between unit and $1 is$N: not; $3 $2yd', + 36: 'The unit is$N: not; alive', + 37: 'The unit\'s health is$N: not; $2 $1 points', + 38: 'The unit\'s health is$N: not; $2 $1%', + 39: '[achievement=$1] $Nwas:is yet to be; achieved on this realm', + 40: 'The unit is$N: not; swimming', + 42: 'The creature is$N: not; $1', + 43: 'The Player has$N: not yet; done [quest=$1] for the day', + 44: 'The unit is$N: not; charmed', + 45: 'The Player $Nhas:doesn\'t have; an active $C$1hunter:summoned; pet', + 46: 'The Player is$N: not; riding a taxi', + 47: 'The Player has$N: not; $2 [quest=$1]', + 48: 'The Player has$N: not; collected $3 towards objective #$2 of [quest=$1]', + 49: 'The current map difficulty is #$1', + 50: 'The Player $C$1$Ncan:can\'t; be:is$N: not;; a Gamemaster' }; + /* end aowow custom */ var LANG = { @@ -4846,6 +4937,11 @@ var LANG = { /* AoWoW: start custom */ + tab_conditions: '[Conditions]', + tab_condition_for: '[Condition for]', + cnd_either: '[Either]', + cnd_or: '[Or]', + // Guide myguides: 'Мои руководства', listguides: '[List of guides]', diff --git a/static/js/locale_zhcn.js b/static/js/locale_zhcn.js index 71724fd6..348b26ef 100644 --- a/static/js/locale_zhcn.js +++ b/static/js/locale_zhcn.js @@ -2454,67 +2454,158 @@ var g_world_object_types = { 7: '玩家尸体' }; -var g_condition_types = { - 1: ['Looting', 'If the conditions are met, this item can be dropped by [npc=$1].'], // CND_SRC_CREATURE_LOOT_TEMPLATE - 2: ['Disenchanting', 'If the conditions are met, this item can be found when disenchanting [item=$1].'], // CND_SRC_DISENCHANT_LOOT_TEMPLATE - 3: ['Fishing', 'If the conditions are met, fishing in [zone=$1] can yield this item.'], // CND_SRC_FISHING_LOOT_TEMPLATE - 4: ['Object Opening', 'If the conditions are met, this item can be found in [object=$1].'], // CND_SRC_GAMEOBJECT_LOOT_TEMPLATE - 5: ['Item Opening', 'If the conditions are met, this item can be found in [item=$1].'], // CND_SRC_ITEM_LOOT_TEMPLATE - 6: ['Mail Attachm.', 'If the conditions are met, this item can be attached to this mail.'], // CND_SRC_MAIL_LOOT_TEMPLATE - 7: ['Milling', 'If the conditions are met, this item can be milled from [item=$1].'], // CND_SRC_MILLING_LOOT_TEMPLATE - 8: ['Pickpocketing', 'If the conditions are met, this item can be picked from [npc=$1].'], // CND_SRC_PICKPOCKETING_LOOT_TEMPLATE - 9: ['Prospecting', 'If the conditions are met, this item can be prospected from [item=$1].'], // CND_SRC_PROSPECTING_LOOT_TEMPLATE - 10: ['Ref. Looting', ''], // CND_SRC_REFERENCE_LOOT_TEMPLATE - 11: ['Skinning', 'If the conditions are met, this item can be skinned from [npc=$1].'], // CND_SRC_SKINNING_LOOT_TEMPLATE - 12: ['Crafting', 'If the conditions are met, casting [spell=$1] may also create this item.'], // CND_SRC_SPELL_LOOT_TEMPLATE - 13: ['Auto Target', 'Only targets matching the conditions can be affected by the spell.'], // CND_SRC_SPELL_IMPLICIT_TARGET - 14: ['Gossip', 'Display the related Gossip entry on [npc=$2], if the conditions are met.'], // CND_SRC_GOSSIP_MENU - 15: ['Gossip Menu', 'Display the related Gossip menu, if the conditions are met.'], // CND_SRC_GOSSIP_MENU_OPTION - 16: ['Vehicle', 'This Creature can be used as a vehicle, if the conditions are met.'], // CND_SRC_CREATURE_TEMPLATE_VEHICLE - 17: ['Spell', 'This Spell can only be cast, if the conditions are met.'], // CND_SRC_SPELL - 18: ['Spell Click', 'If the conditions are met, [npc=$2] casts [spell=$1] if clicked on.'], // CND_SRC_SPELL_CLICK_EVENT - 19: ['Quest Accept', 'The Player can accept this quest, if the condition is met.'], // CND_SRC_QUEST_SHOW_MARK - 20: ['Quest Sign', 'A [icon name=quest_startend] [/icon] will be shown for this quest, if the condition is met.'], // CND_SRC_QUEST_ACCEPT - 21: ['Vehicle Spell', 'If the conditions are met, vehicle [npc=$2] has [spell=$1] available.'], // CND_SRC_VEHICLE_SPELL - 22: ['SmartAI', 'If the conditions are met, the creatures AI may perform additional actions.'], // CND_SRC_SMART_EVENT - 23: ['Vendor', 'If the conditions are met, the vendor will have this item available.'], // CND_SRC_NPC_VENDOR - 24: ['Spell Proc', 'If the conditions are met, the spell is allowed to proc.'] // CND_SRC_SPELL_PROC +var g_instance_info = { + 0: 'Data', + 1: 'GUID', + 2: 'Boss State', + 3: 'Data64' +}; + +var g_unit_states = { + 0: 'Died', + 1: 'Melee attacking', + 2: 'Charmed', + 3: 'Stunned', + 4: 'Roaming', + 5: 'Chase', + 6: 'Focusing', + 7: 'Fleeing', + 8: 'In flight', + 9: 'Follow', + 10: 'Root', + 11: 'Confused', + 12: 'Distracted', + 13: 'Isolated', + 14: 'Attack player', + 15: 'Casting', + 16: 'Possessed', + 17: 'Charging', + 18: 'Jumping', + 19: 'Follow formation', + 20: 'Move', + 21: 'Rotating', + 22: 'Evade', + 23: 'Roaming move', + 24: 'Confused move', + 25: 'Fleeing move', + 26: 'Chase move', + 27: 'Follow move', + 28: 'Ignore pathfinding', + 29: 'Follow formation move' +}; + +var g_relation_types = { + 0: 'is$N: not; itself', + 1: 'is$N: not; in a group with $3', + 2: 'is$N: not; in a raid or party with $3', + 3: 'is$N: not; owned by $3', + 4: 'is$N: not; a passenger of $3', + 5: 'was$N: not; summoned by $3' +}; + +var g_stand_states = { + 0: 'standing', + 1: 'sitting', + 2: 'sitting on a chair', + 3: 'sleeping', + 4: 'sitting on a low chair', + 5: 'sitting on a medium chair', + 6: 'sitting on a high chair', + 7: 'dead', + 8: 'kneeling', + 9: 'submerged' +}; + +var g_quest_states = { + 0: 'not yet seen', + 1: 'completed', + 3: 'taken', + 5: 'failed', + 6: 'been rewarded', +}; + +var g_condition_sources = { + 0: [['player', null], ''], + 1: [['player', null], 'If the conditions are met, [item=$2] can be dropped by [npc=$1].'], + 2: [['player', null], 'If the conditions are met, [item=$2] can be found when disenchanting [item=$1].'], + 3: [['player', null], 'If the conditions are met, fishing in [zone=$1] can yield [item=$2].'], + 4: [['player', null], 'If the conditions are met, [item=$2] can be found in [object=$1].'], + 5: [['player', null], 'If the conditions are met, [item=$2] can be found in [item=$1].'], + 6: [['player', null], 'If the conditions are met, [item=$2] can be attached to the mail from [quest=$1].'], + 7: [['player', null], 'If the conditions are met, [item=$2] can be milled from [item=$1].'], + 8: [['player', null], 'If the conditions are met, [item=$2] can be picked from [npc=$1].'], + 9: [['player', null], 'If the conditions are met, [item=$2] can be prospected from [item=$1].'], + 10: [['player', null], 'If the conditions are met, [item=$2] will be referenced in template #$1.'], + 11: [['player', null], 'If the conditions are met, [item=$2] can be gathered from [npc=$1].'], + 12: [['player', null], 'If the conditions are met, casting [spell=$1] may also create [item=$2].'], + 13: [['target', 'caster'], 'Only a $T%:spell%; matching the conditions can be affected by [spell=$2].'], + 14: [['player', 'entity'], 'Display Gossip text #$2 from menu #$1, if the conditions on the $T%:%; are met.'], + 15: [['player', 'entity'], 'Display Gossip option #$2 from menu #$1, if the conditions on the $T%:%; are met.'], + 16: [['player', 'creature'], '[npc=$2] can be used as a vehicle, if $Tthe %s:its; conditions are met.'], + 17: [['caster', 'target'], '[spell=$2] can only be cast, if the $Tspell%s:%s; conditions are met.'], + 18: [['player', 'creature'], 'If the $T%s:%s; conditions are met, [npc=$1] casts [spell=$2] if clicked on.'], + 19: [['player', null], 'The Player can accept [quest=$2], if the condition is met.'], + 20: [['player', null], 'A [icon name=quest_startend] [/icon] will be shown for [quest=$2], if the condition is met.'], + 21: [['player', 'creature'], 'If the $T%s:%s; conditions are met, vehicle [npc=$1] has [spell=$2] available.'], + 22: [['invoker', 'entity'], 'If the conditions for the $T%:%; are met, the AI may perform additional actions.'], + 23: [['player', 'creature'], 'If the conditions for the $T%:%; are met, [npc=$1] will have [item=$2] for sale.'], + 24: [['caster', 'target'], 'If the conditions for the $Tspell%:%; are met, the [spell=$2] is allowed to proc.'], + 30: [['player', null], 'If the conditions are met, [url=?areatrigger=$2]Areatrigger #$2[/url] is allowed to trigger.'] }; var g_conditions = { - 1: 'The Player $has:does not have; an aura of $1', - 2: 'The Player $owns: does not own; $1', - 3: 'The Player $has:does not have; $1 equipped', - 4: 'The Player is$: not; in $1', // also used by 22, 23 - 5: '玩家声望关系和$1是$:不是;$2', - 6: '玩家是$:不是;$1', - 7: 'The Player $knows: does not know; $1', - 8: 'The Player has$: not; finished $1', - 9: '玩家已经$:没有;接受$1', - 10: 'The Player is$: not; $1', - 11: 'WorldState #$1 is$: not; $2', - 12: '$1 must$: not; be active', - 13: 'The instance $has:does not have; a certain state', // nyi - 14: 'The Player has $never:; interacted with $1', - 15: 'The Player is$: not; a $1', // also used by 16 - 17: 'The Player has$: not; achieved $1', - 18: 'The Player has$: not; obtained $1', - 20: 'The Player\'s gender is$: not; [span class=icon-$2]$1[/span]', - 21: 'The target $has:does not have; a certain state', // nyi - 24: '', // not used - 25: 'The Player $knows: does not know; $1', - 26: 'The Creature is$: not; in phase $1', - 27: 'The target\'s level is$: not; $2 $1', - 28: 'The Player has$: not; completed $1', - 29: 'The Player is$: not; within $2yd of $1', // also used by 30 - 31: 'Casters\'s target is$: not; $1', // also used by 32 - 33: 'The Player $has:does not have; a certain relation to the target', // nyi - 34: 'The target $has:does not have; a certain reaction to the Player', // nyi - 35: 'The target is$: not; $2 $1yd away', - 36: 'The target is$: not; alive', - 37: 'The target\'s health is$: not; $2 $1', - 38: 'The target\'s health is$: not; $2 $1%' + 0: 'Always $Ntrue:false;', + 1: 'The target $Nhas:does not have; an aura of [spell=$1]', + 2: 'The Player $Nhas:does not have; $2 [item=$1] in their inventory$C$3 or bank:;', + 3: 'The Player $Nhas:does not have; [item=$1] equipped', + 4: 'The Player is$N: not; in [zone=$1]', + 5: 'The Player\'s standing with [faction=$1] is$N: not; $2', // '玩家声望关系和$1是$:不是;$2' + 6: 'The Player is$N: not; a member of the $1', // '玩家是$:不是;$1' + 7: 'The Player is$N: not; proficient in [skill=$1]$C$2 (min. $2):;', + 8: 'The Player was$N: not; rewarded [quest=$1]', + 9: 'The Player has$N: not; accepted [quest=$1]', // '玩家已经$:没有;接受$1' + 10: 'The Player is$N: not; $1', + 11: 'WorldState #$1 is$N: not; $2', + 12: '[event=$1] must$N: not; be active', + 13: 'The instance\'s $3 at index #$1 is$N: not; equal to "$2"', + 14: 'The Player has $Nnever:; interacted with [quest=$1]', + 15: 'The Player is$N: not; a $1', + 16: 'The Player is$N: not; a $1', + 17: 'The Player has$N: not; achieved [achievement=$1]', + 18: 'The Player has$N: not; obtained [title=$1]', + 19: 'The entity\'s SpawnMask is$N: not; equal to "$1"', + 20: 'The Player\'s gender is$N: not; $1', + 21: 'The unit\'s state is$N: not; $1', + 22: 'The target is$N: not; in $1', + 23: 'The target is$N: not; in [zone=$1]', + 24: 'The creature is$N: not; a $1', + 25: 'The Player $Nknows: does not know; [spell=$1]', + 26: 'The entity is$N: not; in phase $1', + 27: 'The target\'s level is$N: not; $2 $1', + 28: 'The Player has$N: not; completed [quest=$1]', + 29: 'The target is$N: not; within $2yd of $C$3deceased:alive; [npc=$1]', + 30: 'The target is$N: not; within $2yd of [object=$1]', + 31: 'The entity is$N: not; $C$2: a; $1$C$3 (GUID $3):;', + 32: 'The entity is$N: not; a $1', + 33: '$1 $2', + 34: 'The unit is$N: not; $2 to $1', + 35: 'The distance between unit and $1 is$N: not; $3 $2yd', + 36: 'The unit is$N: not; alive', + 37: 'The unit\'s health is$N: not; $2 $1 points', + 38: 'The unit\'s health is$N: not; $2 $1%', + 39: '[achievement=$1] $Nwas:is yet to be; achieved on this realm', + 40: 'The unit is$N: not; swimming', + 42: 'The creature is$N: not; $1', + 43: 'The Player has$N: not yet; done [quest=$1] for the day', + 44: 'The unit is$N: not; charmed', + 45: 'The Player $Nhas:doesn\'t have; an active $C$1hunter:summoned; pet', + 46: 'The Player is$N: not; riding a taxi', + 47: 'The Player has$N: not; $2 [quest=$1]', + 48: 'The Player has$N: not; collected $3 towards objective #$2 of [quest=$1]', + 49: 'The current map difficulty is #$1', + 50: 'The Player $C$1$Ncan:can\'t; be:is$N: not;; a Gamemaster' }; + /* end aowow custom */ var LANG = { @@ -4869,6 +4960,11 @@ var LANG = { /* AoWoW: start custom */ + tab_conditions: '[Conditions]', + tab_condition_for: '[Condition for]', + cnd_either: '[Either]', + cnd_or: '[Or]', + // Guide myguides: '我的指南', listguides: '[List of guides]',