mirror of
https://github.com/Sarjuuk/aowow.git
synced 2025-11-29 15:58:16 +08:00
Core/Conditions
* rewritten and moved to its own class, should be easier to expand in the future * add missing sources and types from TrinityCore * implement conditions on Areatrigger and Loot containers * implement reverse lookups (e.g. a spell is a conditional for something else) * general beautification pass .. should be more legible in general NOTE: * texts have been changed, so the existing translation for esES ist gone * selecting and describing condition targets is still wonky
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user