diff --git a/includes/defines.php b/includes/defines.php
index 3864c540..fda8c801 100644
--- a/includes/defines.php
+++ b/includes/defines.php
@@ -481,6 +481,10 @@ define('TEAM_ALLIANCE', 0);
define('TEAM_HORDE', 1);
define('TEAM_NEUTRAL', 2);
+// Lock Types
+define('LOCK_TYPE_ITEM', 1);
+define('LOCK_TYPE_SKILL', 2);
+
// Lock-Properties (also categorizes GOs)
define('LOCK_PROPERTY_FOOTLOCKER', 1);
define('LOCK_PROPERTY_HERBALISM', 2);
diff --git a/includes/types/gameobject.class.php b/includes/types/gameobject.class.php
index a6d23ce6..99cf284d 100644
--- a/includes/types/gameobject.class.php
+++ b/includes/types/gameobject.class.php
@@ -103,7 +103,7 @@ class GameObjectList extends BaseType
if (isset($this->curTpl['lockId']))
if ($locks = Lang::getLocks($this->curTpl['lockId']))
foreach ($locks as $l)
- $x .= '
| '.$l.' |
';
+ $x .= '| '.sprintf(Lang::game('requires'), $l).' |
';
$x .= '';
diff --git a/includes/types/item.class.php b/includes/types/item.class.php
index 61518a8f..8e3f0948 100644
--- a/includes/types/item.class.php
+++ b/includes/types/item.class.php
@@ -918,8 +918,8 @@ class ItemList extends BaseType
$x .= sprintf(Lang::game('requires'), ''.FactionList::getName($reqFac).' - '.Lang::game('rep', $this->curTpl['requiredFactionRank'])).'
';
// locked or openable
- if ($locks = Lang::getLocks($this->curTpl['lockId'], true))
- $x .= ''.Lang::item('locked').'
'.implode('
', $locks).'
';
+ if ($locks = Lang::getLocks($this->curTpl['lockId'], $arr, true, true))
+ $x .= ''.Lang::item('locked').'
'.implode('
', array_map(function($x) { return sprintf(Lang::game('requires'), $x); }, $locks)).'
';
else if ($this->curTpl['flags'] & ITEM_FLAG_OPENABLE)
$x .= ''.Lang::item('openClick').'
';
diff --git a/includes/utilities.php b/includes/utilities.php
index 6f557664..4aed8c51 100644
--- a/includes/utilities.php
+++ b/includes/utilities.php
@@ -525,21 +525,21 @@ class Util
if ($short)
{
if ($_ = round($d / 364))
- return $_." ".Lang::timeUnits('ab', 0);
+ return $_." ".Lang::timeUnits('ab', 0);
if ($_ = round($d / 30))
- return $_." ".Lang::timeUnits('ab', 1);
+ return $_." ".Lang::timeUnits('ab', 1);
if ($_ = round($d / 7))
- return $_." ".Lang::timeUnits('ab', 2);
+ return $_." ".Lang::timeUnits('ab', 2);
if ($_ = round($d))
- return $_." ".Lang::timeUnits('ab', 3);
+ return $_." ".Lang::timeUnits('ab', 3);
if ($_ = round($h))
- return $_." ".Lang::timeUnits('ab', 4);
+ return $_." ".Lang::timeUnits('ab', 4);
if ($_ = round($m))
- return $_." ".Lang::timeUnits('ab', 5);
+ return $_." ".Lang::timeUnits('ab', 5);
if ($_ = round($s + $ms / 1000, 2))
- return $_." ".Lang::timeUnits('ab', 6);
+ return $_." ".Lang::timeUnits('ab', 6);
if ($ms)
- return $ms." ".Lang::timeUnits('ab', 7);
+ return $ms." ".Lang::timeUnits('ab', 7);
return '0 '.Lang::timeUnits('ab', 6);
}
@@ -547,19 +547,19 @@ class Util
{
$_ = $d + $h / 24;
if ($_ > 1 && !($_ % 364)) // whole years
- return round(($d + $h / 24) / 364, 2)." ".Lang::timeUnits($d / 364 == 1 && !$h ? 'sg' : 'pl', 0);
+ return round(($d + $h / 24) / 364, 2)." ".Lang::timeUnits($d / 364 == 1 && !$h ? 'sg' : 'pl', 0);
if ($_ > 1 && !($_ % 30)) // whole month
- return round(($d + $h / 24) / 30, 2)." ".Lang::timeUnits($d / 30 == 1 && !$h ? 'sg' : 'pl', 1);
+ return round(($d + $h / 24) / 30, 2)." ".Lang::timeUnits($d / 30 == 1 && !$h ? 'sg' : 'pl', 1);
if ($_ > 1 && !($_ % 7)) // whole weeks
- return round(($d + $h / 24) / 7, 2)." ".Lang::timeUnits($d / 7 == 1 && !$h ? 'sg' : 'pl', 2);
+ return round(($d + $h / 24) / 7, 2)." ".Lang::timeUnits($d / 7 == 1 && !$h ? 'sg' : 'pl', 2);
if ($d)
- return round($d + $h / 24, 2)." ".Lang::timeUnits($d == 1 && !$h ? 'sg' : 'pl', 3);
+ return round($d + $h / 24, 2)." ".Lang::timeUnits($d == 1 && !$h ? 'sg' : 'pl', 3);
if ($h)
- return round($h + $m / 60, 2)." ".Lang::timeUnits($h == 1 && !$m ? 'sg' : 'pl', 4);
+ return round($h + $m / 60, 2)." ".Lang::timeUnits($h == 1 && !$m ? 'sg' : 'pl', 4);
if ($m)
- return round($m + $s / 60, 2)." ".Lang::timeUnits($m == 1 && !$s ? 'sg' : 'pl', 5);
+ return round($m + $s / 60, 2)." ".Lang::timeUnits($m == 1 && !$s ? 'sg' : 'pl', 5);
if ($s)
- return round($s + $ms / 1000, 2)." ".Lang::timeUnits($s == 1 && !$ms ? 'sg' : 'pl', 6);
+ return round($s + $ms / 1000, 2)." ".Lang::timeUnits($s == 1 && !$ms ? 'sg' : 'pl', 6);
if ($ms)
return $ms." ".Lang::timeUnits($ms == 1 ? 'sg' : 'pl', 7);
diff --git a/localization/lang.class.php b/localization/lang.class.php
index 324a0f25..5c3ace07 100644
--- a/localization/lang.class.php
+++ b/localization/lang.class.php
@@ -227,9 +227,10 @@ class Lang
return $tmp;
}
- public static function getLocks($lockId, $interactive = false)
+ public static function getLocks(int $lockId, ?array &$ids = [], bool $interactive = false, bool $asHTML = false) : array
{
$locks = [];
+ $ids = [];
$lock = DB::Aowow()->selectRow('SELECT * FROM ?_lock WHERE id = ?d', $lockId);
if (!$lock)
return $locks;
@@ -240,47 +241,71 @@ class Lang
$rank = $lock['reqSkill'.$i];
$name = '';
- if ($lock['type'.$i] == 1) // opened by item
+ if ($lock['type'.$i] == LOCK_TYPE_ITEM)
{
$name = ItemList::getName($prop);
if (!$name)
continue;
- if ($interactive)
+ if ($interactive && $asHTML)
$name = ''.$name.'';
+ else if ($interactive && !$asHTML)
+ {
+ $name = '[item='.$prop.']';
+ $ids[TYPE_ITEM][] = $prop;
+ }
}
- else if ($lock['type'.$i] == 2) // opened by skill
+ else if ($lock['type'.$i] == LOCK_TYPE_SKILL)
{
- // exclude unusual stuff
- if (!in_array($prop, [1, 2, 3, 4, 9, 16, 20]))
- continue;
-
$name = self::spell('lockType', $prop);
if (!$name)
continue;
- if ($interactive)
+ // skills
+ if (in_array($prop, [1, 2, 3, 20]))
{
- $skill = 0;
- switch ($prop)
+ $skills = array(
+ 1 => SKILL_LOCKPICKING,
+ 2 => SKILL_HERBALISM,
+ 3 => SKILL_MINING,
+ 20 => SKILL_INSCRIPTION
+ );
+
+ if ($interactive && $asHTML)
+ $name = ''.$name.'';
+ else if ($interactive && !$asHTML)
{
- case 1: $skill = 633; break; // Lockpicking
- case 2: $skill = 182; break; // Herbing
- case 3: $skill = 186; break; // Mining
- case 20: $skill = 773; break; // Scribing
+ $name = '[skill='.$skills[$prop].']';
+ $ids[TYPE_SKILL][] = $skills[$prop];
}
- if ($skill)
- $name = ''.$name.'';
+ if ($rank > 0)
+ $name .= ' ('.$rank.')';
}
-
- if ($rank > 0)
- $name .= ' ('.$rank.')';
+ // Lockpicking
+ else if ($prop == 4)
+ {
+ if ($interactive && $asHTML)
+ $name = ''.$name.'';
+ else if ($interactive && !$asHTML)
+ {
+ $name = '[spell=1842]';
+ $ids[TYPE_SPELL][] = 1842;
+ }
+ }
+ // exclude unusual stuff
+ else if (User::isInGroup(U_GROUP_STAFF))
+ {
+ if ($rank > 0)
+ $name .= ' ('.$rank.')';
+ }
+ else
+ continue;
}
else
continue;
- $locks[$lock['type'.$i] == 1 ? $prop : -$prop] = sprintf(self::game('requires'), $name);
+ $locks[$lock['type'.$i] == LOCK_TYPE_ITEM ? $prop : -$prop] = $name;
}
return $locks;
diff --git a/pages/object.php b/pages/object.php
index 9c005702..05a19661 100644
--- a/pages/object.php
+++ b/pages/object.php
@@ -101,20 +101,22 @@ class ObjectPage extends GenericPage
break;
default: // requires key .. maybe
{
- $locks = Lang::getLocks($this->subject->getField('lockId'));
- $l = '';
- foreach ($locks as $idx => $_)
- {
- if ($idx < 0)
- continue;
+ $locks = Lang::getLocks($this->subject->getField('lockId'), $ids, true);
+ $l = [];
- $this->extendGlobalIds(TYPE_ITEM, $idx);
- $l = Lang::gameObject('key').Lang::main('colon').'[item='.$idx.']';
+ foreach ($ids as $type => $typeIds)
+ $this->extendGlobalIds($type, ...$typeIds);
+
+ foreach ($locks as $idx => $str)
+ {
+ if ($idx > 0)
+ $l[] = Lang::gameObject('key').Lang::main('colon').$str;
+ else if ($idx < 0)
+ $l[] = sprintf(Lang::game('requires'), $str);
}
- // if no propper item is found use a skill
- if ($locks)
- $infobox[] = $l ?: array_pop($locks);
+ if ($l)
+ $infobox[] = implode('[br]', $l);
}
}
diff --git a/setup/tools/dbc.class.php b/setup/tools/dbc.class.php
index b2e67dae..70e08a77 100644
--- a/setup/tools/dbc.class.php
+++ b/setup/tools/dbc.class.php
@@ -92,6 +92,7 @@ class DBC
'itemsubclass' => 'iixxxxxxxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'lfgdungeons' => 'nsxsssxsxsxxxxxxxxiiiiiiixiixixixxxxxxxxxxxxxxxxx',
'lock' => 'niiiiixxxiiiiixxxiiiiixxxxxxxxxxx',
+ 'locktype' => 'nsxsssxsxsxxxxxxxxsxsssxsxsxxxxxxxxsxsssxsxsxxxxxxxxs',
'mailtemplate' => 'nsxsssxsxsxxxxxxxxsxsssxsxsxxxxxxxx',
'map' => 'nsixisxsssxsxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiffxixi',
'mapdifficulty' => 'niixxxxxxxxxxxxxxxxxxis',
@@ -195,6 +196,7 @@ class DBC
'itemsubclass' => 'class,subClass,weaponSize',
'lfgdungeons' => 'id,name_loc0,name_loc2,name_loc3,name_loc4,name_loc6,name_loc8,levelMin,levelMax,targetLevel,targetLevelMin,targetLevelMax,mapId,difficulty,type,faction,expansion,groupId',
'lock' => 'id,type1,type2,type3,type4,type5,properties1,properties2,properties3,properties4,properties5,reqSkill1,reqSkill2,reqSkill3,reqSkill4,reqSkill5',
+ 'locktype' => 'id,name_loc0,name_loc2,name_loc3,name_loc4,name_loc6,name_loc8,state_loc0,state_loc2,state_loc3,state_loc4,state_loc6,state_loc8,process_loc0,process_loc2,process_loc3,process_loc4,process_loc6,process_loc8,strref',
'mailtemplate' => 'id,subject_loc0,subject_loc2,subject_loc3,subject_loc4,subject_loc6,subject_loc8,text_loc0,text_loc2,text_loc3,text_loc4,text_loc6,text_loc8',
'map' => 'id,nameINT,areaType,isBG,name_loc0,name_loc2,name_loc3,name_loc4,name_loc6,name_loc8,parentMapId,parentX,parentY,expansion,maxPlayers',
'mapdifficulty' => 'id,mapId,difficulty,nPlayer,nPlayerString',