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]',