diff --git a/endpoints/item/item.php b/endpoints/item/item.php
index 03f5da42..8f90208d 100644
--- a/endpoints/item/item.php
+++ b/endpoints/item/item.php
@@ -592,12 +592,14 @@ class ItemBaseResponse extends TemplateResponse implements ICache
), SpellList::$brickFile));
}
- // tab: unlocks (object or item) - LOCK_TYPE_ITEM: 1
+ // tab: unlocks (object or item)
$lockIds = DB::Aowow()->selectCol(
- 'SELECT `id` FROM ?_lock WHERE (`type1` = 1 AND `properties1` = ?d) OR
- (`type2` = 1 AND `properties2` = ?d) OR (`type3` = 1 AND `properties3` = ?d) OR
- (`type4` = 1 AND `properties4` = ?d) OR (`type5` = 1 AND `properties5` = ?d)',
- $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId
+ 'SELECT `id` FROM ?_lock WHERE (`type1` = ?d AND `properties1` = ?d) OR
+ (`type2` = ?d AND `properties2` = ?d) OR (`type3` = ?d AND `properties3` = ?d) OR
+ (`type4` = ?d AND `properties4` = ?d) OR (`type5` = ?d AND `properties5` = ?d)',
+ LOCK_TYPE_ITEM, $this->typeId, LOCK_TYPE_ITEM, $this->typeId,
+ LOCK_TYPE_ITEM, $this->typeId, LOCK_TYPE_ITEM, $this->typeId,
+ LOCK_TYPE_ITEM, $this->typeId
);
if ($lockIds)
diff --git a/endpoints/spell/spell.php b/endpoints/spell/spell.php
index 0ab1ee92..9f651ada 100644
--- a/endpoints/spell/spell.php
+++ b/endpoints/spell/spell.php
@@ -1166,6 +1166,55 @@ class SpellBaseResponse extends TemplateResponse implements ICache
}
}
+ // tab: unlocks (object or item)
+ $lockIds = DB::Aowow()->selectCol(
+ 'SELECT `id` FROM ?_lock WHERE (`type1` = ?d AND `properties1` = ?d) OR
+ (`type2` = ?d AND `properties2` = ?d) OR (`type3` = ?d AND `properties3` = ?d) OR
+ (`type4` = ?d AND `properties4` = ?d) OR (`type5` = ?d AND `properties5` = ?d)',
+ LOCK_TYPE_SPELL, $this->typeId, LOCK_TYPE_SPELL, $this->typeId,
+ LOCK_TYPE_SPELL, $this->typeId, LOCK_TYPE_SPELL, $this->typeId,
+ LOCK_TYPE_SPELL, $this->typeId
+ );
+
+ // we know this spell effect is only in use on index 1
+ if ($this->subject->getField('effect1Id') == SPELL_EFFECT_OPEN_LOCK && ($lockId = $this->subject->getField('effect1MiscValue')))
+ $lockIds += DB::Aowow()->selectCol(
+ 'SELECT `id` FROM ?_lock WHERE (`type1` = ?d AND `properties1` = ?d) OR
+ (`type2` = ?d AND `properties2` = ?d) OR (`type3` = ?d AND `properties3` = ?d) OR
+ (`type4` = ?d AND `properties4` = ?d) OR (`type5` = ?d AND `properties5` = ?d)',
+ LOCK_TYPE_SKILL, $lockId, LOCK_TYPE_SKILL, $lockId,
+ LOCK_TYPE_SKILL, $lockId, LOCK_TYPE_SKILL, $lockId,
+ LOCK_TYPE_SKILL, $lockId
+ );
+
+ if ($lockIds)
+ {
+ // objects
+ $lockedObj = new GameObjectList(array(Cfg::get('SQL_LIMIT_NONE'), ['lockId', $lockIds]));
+ if (!$lockedObj->error)
+ {
+ $this->addDataLoader('zones');
+ $this->lvTabs->addListviewTab(new Listview(array(
+ 'data' => $lockedObj->getListviewData(),
+ 'name' => '$LANG.tab_unlocks',
+ 'id' => 'unlocks-object',
+ 'visibleCols' => $lockedObj->hasSetFields('reqSkill') ? ['skill'] : null
+ ), GameObjectList::$brickFile));
+ }
+
+ $lockedItm = new ItemList(array(Cfg::get('SQL_LIMIT_NONE'), ['lockId', $lockIds]));
+ if (!$lockedItm->error)
+ {
+ $this->extendGlobalData($lockedItm->getJSGlobals(GLOBALINFO_SELF));
+
+ $this->lvTabs->addListviewTab(new Listview(array(
+ 'data' => $lockedItm->getListviewData(),
+ 'name' => '$LANG.tab_unlocks',
+ 'id' => 'unlocks-item'
+ ), ItemList::$brickFile));
+ }
+ }
+
// find associated NPC, Item and merge results
// taughtbypets (unused..?)
// taughtbyquest (usually the spell casted as quest reward teaches something; exclude those seplls from taughtBySpell)
diff --git a/includes/dbtypes/gameobject.class.php b/includes/dbtypes/gameobject.class.php
index bcdc0c84..f79db7e6 100644
--- a/includes/dbtypes/gameobject.class.php
+++ b/includes/dbtypes/gameobject.class.php
@@ -99,7 +99,7 @@ class GameObjectList extends DBTypeList
if (isset($this->curTpl['lockId']))
if ($locks = Lang::getLocks($this->curTpl['lockId']))
foreach ($locks as $l)
- $x .= '
| '.sprintf(Lang::game('requires'), $l).' |
';
+ $x .= '| '.Lang::game('requires', [$l]).' |
';
$x .= '';
diff --git a/includes/dbtypes/item.class.php b/includes/dbtypes/item.class.php
index 4bec8f3e..10c4fc1d 100644
--- a/includes/dbtypes/item.class.php
+++ b/includes/dbtypes/item.class.php
@@ -937,7 +937,7 @@ class ItemList extends DBTypeList
// locked or openable
if ($locks = Lang::getLocks($this->curTpl['lockId'], $arr, true))
- $x .= ''.Lang::item('locked').'
'.implode('
', array_map(function($x) { return sprintf(Lang::game('requires'), $x); }, $locks)).'
';
+ $x .= ''.Lang::item('locked').'
'.implode('
', array_map(fn($x) => Lang::game('requires', [$x]), $locks)).'
';
else if ($this->curTpl['flags'] & ITEM_FLAG_OPENABLE)
$x .= ''.Lang::item('openClick').'
';
diff --git a/includes/defines.php b/includes/defines.php
index 4894f295..03cf0fce 100644
--- a/includes/defines.php
+++ b/includes/defines.php
@@ -609,6 +609,7 @@ define('TEAM_NEUTRAL', 2);
// Lock Types
define('LOCK_TYPE_ITEM', 1);
define('LOCK_TYPE_SKILL', 2);
+define('LOCK_TYPE_SPELL', 3);
// Lock-Properties (also categorizes GOs)
define('LOCK_PROPERTY_FOOTLOCKER', 1);
diff --git a/localization/lang.class.php b/localization/lang.class.php
index c0aa3080..bdedb1c1 100644
--- a/localization/lang.class.php
+++ b/localization/lang.class.php
@@ -267,75 +267,87 @@ class Lang
$rank = $lock['reqSkill'.$i];
$name = '';
- if ($lock['type'.$i] == LOCK_TYPE_ITEM)
+ switch ($lock['type'.$i])
{
- $name = ItemList::getName($prop);
- if (!$name)
- continue;
-
- if ($fmt == self::FMT_HTML)
- $name = $interactive ? ''.$name.'' : ''.$name.'';
- else if ($interactive && $fmt == self::FMT_MARKUP)
- {
- $name = '[item='.$prop.']';
- $ids[Type::ITEM][] = $prop;
- }
- else
- $name = $prop;
-
- }
- else if ($lock['type'.$i] == LOCK_TYPE_SKILL)
- {
- $name = self::spell('lockType', $prop);
- if (!$name)
- continue;
-
- // skills
- if (in_array($prop, [1, 2, 3, 20]))
- {
- $skills = array(
- 1 => SKILL_LOCKPICKING,
- 2 => SKILL_HERBALISM,
- 3 => SKILL_MINING,
- 20 => SKILL_INSCRIPTION
- );
+ case LOCK_TYPE_ITEM:
+ $name = ItemList::getName($prop);
+ if (!$name)
+ continue 2;
if ($fmt == self::FMT_HTML)
- $name = $interactive ? ''.$name.'' : ''.$name.'';
+ $name = $interactive ? ''.$name.'' : ''.$name.'';
else if ($interactive && $fmt == self::FMT_MARKUP)
{
- $name = '[skill='.$skills[$prop].']';
- $ids[Type::SKILL][] = $skills[$prop];
+ $name = '[item='.$prop.']';
+ $ids[Type::ITEM][] = $prop;
+ }
+
+ break;
+ case LOCK_TYPE_SKILL:
+ $name = self::spell('lockType', $prop);
+ if (!$name)
+ continue 2;
+
+ // skills
+ if (in_array($prop, [1, 2, 3, 20]))
+ {
+ $skills = array(
+ 1 => SKILL_LOCKPICKING,
+ 2 => SKILL_HERBALISM,
+ 3 => SKILL_MINING,
+ 20 => SKILL_INSCRIPTION
+ );
+
+ if ($fmt == self::FMT_HTML)
+ $name = $interactive ? ''.$name.'' : ''.$name.'';
+ else if ($interactive && $fmt == self::FMT_MARKUP)
+ {
+ $name = '[skill='.$skills[$prop].']';
+ $ids[Type::SKILL][] = $skills[$prop];
+ }
+ else
+ $name = SkillList::getName($prop);
+
+ if ($rank > 0)
+ $name .= ' ('.$rank.')';
+ }
+ // Lockpicking
+ else if ($prop == 4)
+ {
+ if ($fmt == self::FMT_HTML)
+ $name = $interactive ? ''.$name.'' : ''.$name.'';
+ else if ($interactive && $fmt == self::FMT_MARKUP)
+ {
+ $name = '[spell=1842]';
+ $ids[Type::SPELL][] = 1842;
+ }
+ }
+ // exclude unusual stuff
+ else if (User::isInGroup(U_GROUP_STAFF))
+ {
+ if ($rank > 0)
+ $name .= ' ('.$rank.')';
}
else
- $name = $skills[$prop];
+ continue 2;
+ break;
+ case LOCK_TYPE_SPELL:
+ $name = SpellList::getName($prop);
+ if (!$name)
+ continue 2;
- if ($rank > 0)
- $name .= ' ('.$rank.')';
- }
- // Lockpicking
- else if ($prop == 4)
- {
if ($fmt == self::FMT_HTML)
- $name = $interactive ? ''.$name.'' : ''.$name.'';
+ $name = $interactive ? ''.$name.'' : ''.$name.'';
else if ($interactive && $fmt == self::FMT_MARKUP)
{
- $name = '[spell=1842]';
- $ids[Type::SPELL][] = 1842;
+ $name = '[spell='.$prop.']';
+ $ids[Type::SPELL][] = $prop;
}
- // else $name = $name
- }
- // exclude unusual stuff
- else if (User::isInGroup(U_GROUP_STAFF))
- {
- if ($rank > 0)
- $name .= ' ('.$rank.')';
- }
- else
- continue;
+
+ break;
+ default:
+ continue 2;
}
- else
- continue;
$locks[$lock['type'.$i] == LOCK_TYPE_ITEM ? $prop : -$prop] = $name;
}