Setup/Stats

* fix stat calculation for food by including triggered spells
This commit is contained in:
Sarjuuk 2025-11-27 20:00:06 +01:00
parent 2305d8bf13
commit f955c67026
3 changed files with 45 additions and 29 deletions

View file

@ -400,11 +400,14 @@ class StatsContainer implements \Countable
return $this;
}
public function fromSpell(array $spell) : self
public function fromSpell(array $spell, bool $onlyFoodBuff = false) : self
{
if (!$spell)
return $this;
if ($onlyFoodBuff && !($spell['attributes2'] & SPELL_ATTR2_FOOD_BUFF))
return $this;
// if spells grant an equal, non-zero amount of SPELL_DAMAGE and SPELL_HEALING, combine them to SPELL_POWER
// this probably does not affect enchantments
$tmpStore = [];
@ -418,6 +421,11 @@ class StatsContainer implements \Countable
if (in_array($eff, SpellList::EFFECTS_ENCHANTMENT) && ($relE = $this->relE($mVal)))
$this->fromEnchantment($relE);
else if ($aura == SPELL_AURA_PERIODIC_TRIGGER_SPELL && ($ts = $spell['effect'.$i.'TriggerSpell']))
{
if ($relS = $this->relS($ts))
$this->fromSpell($relS, true);
}
else
foreach ($this->convertSpellEffect($aura, $mVal, $amt) as $idx)
Util::arraySumByKey($tmpStore, [$idx => $amt]);
@ -519,18 +527,12 @@ class StatsContainer implements \Countable
private function relE(int $enchantmentId) : array
{
if ($enchantmentId <= 0 || !isset($this->relEnchantments[$enchantmentId]))
return [];
return $this->relEnchantments[$enchantmentId];
return $this->relEnchantments[$enchantmentId] ?? [];
}
private function relS(int $spellId) : array
{
if ($spellId <= 0 || !isset($this->relSpells[$spellId]))
return [];
return $this->relSpells[$spellId];
return $this->relSpells[$spellId] ?? [];
}
private static function convertEnchantment(int $type, int $object) : array

View file

@ -0,0 +1 @@
UPDATE `aowow_dbversion` SET `sql` = CONCAT(IFNULL(`sql`, ''), ' stats');

View file

@ -11,17 +11,14 @@ if (!CLI)
class ItemStatSetup extends ItemList
{
private $relSpells = [];
private $relEnchants = [];
public function __construct($start, $limit, array $ids, array $relEnchants, array $relSpells)
public function __construct(int $start, int $limit, int $itemClass, array $ids, private bool $applyTriggered, private array $relEnchants, private array $relSpells)
{
$this->queryOpts['i']['o'] = 'i.id ASC';
unset($this->queryOpts['is']); // do not reference the stats table we are going to write to
$conditions = array(
['i.id', $start, '>'],
['class', [ITEM_CLASS_WEAPON, ITEM_CLASS_GEM, ITEM_CLASS_ARMOR, ITEM_CLASS_CONSUMABLE, ITEM_CLASS_AMMUNITION]],
['class', $itemClass],
$limit
);
@ -29,23 +26,29 @@ class ItemStatSetup extends ItemList
$conditions[] = ['id', $ids];
parent::__construct($conditions);
$this->relSpells = $relSpells;
$this->relEnchants = $relEnchants;
}
public function writeStatsTable() : void
{
foreach ($this->iterate() as $id => $curTpl)
{
$spellIds = [];
$spellIds = [];
for ($i = 1; $i <= 5; $i++)
if ($this->curTpl['spellId'.$i] > 0 && !isset($this->relSpells[$this->curTpl['spellId'.$i]]) && (($this->curTpl['class'] == ITEM_CLASS_CONSUMABLE && $this->curTpl['spellTrigger'.$i] == SPELL_TRIGGER_USE) || $this->curTpl['spellTrigger'.$i] == SPELL_TRIGGER_EQUIP))
$spellIds[] = $this->curTpl['spellId'.$i];
if ($spellIds) // array_merge kills the keys
$this->relSpells = array_replace($this->relSpells, DB::Aowow()->select('SELECT *, id AS ARRAY_KEY FROM ?_spell WHERE id IN (?a)', $spellIds));
{
$newSpells = DB::Aowow()->select('SELECT *, id AS ARRAY_KEY FROM ?_spell WHERE id IN (?a)', $spellIds);
$this->relSpells = array_replace($this->relSpells, $newSpells);
// include triggered spell to calculate nutritional values
if ($this->applyTriggered)
if ($t = array_filter(array_merge(array_column($newSpells, 'effect1TriggerSpell'), array_column($newSpells, 'effect2TriggerSpell'), array_column($newSpells, 'effect3TriggerSpell'))))
if ($t = array_diff($t, array_keys($this->relSpells)))
$this->relSpells = array_replace($this->relSpells, DB::Aowow()->select('SELECT *, id AS ARRAY_KEY FROM ?_spell WHERE id IN (?a)', $t));
}
// fromItem: itemMods, spell, enchants from template - fromJson: calculated stats (feralAP, dps, ...)
if ($stats = (new StatsContainer($this->relSpells, $this->relEnchants))->fromItem($curTpl)->fromJson($this->json[$id])->toJson(Stat::FLAG_ITEM | Stat::FLAG_SERVERSIDE))
@ -75,7 +78,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript
protected $dbcSourceFiles = ['spellitemenchantment'];
protected $setupAfter = [['items', 'spell'], []];
private $relSpells = [];
private array $relSpells = [];
private function enchantment_stats(?int &$total = 0, ?int &$effective = 0) : array
{
@ -114,19 +117,29 @@ CLISetup::registerSetup("sql", new class extends SetupScript
CLI::write('[stats] - applying stats for items');
$i = 0;
$offset = 0;
while (true)
$classes = array(
ITEM_CLASS_WEAPON => [false, 'weapons'],
ITEM_CLASS_ARMOR => [false, 'armor'],
ITEM_CLASS_GEM => [false, 'gems'],
ITEM_CLASS_CONSUMABLE => [true, 'consumables'],
ITEM_CLASS_AMMUNITION => [false, 'ammunition']
);
foreach ($classes as $itemClass => [$applyTriggered, $name])
{
$items = new ItemStatSetup($offset, CLISetup::SQL_BATCH, $ids, $enchStats, $this->relSpells);
if ($items->error)
break;
$i = 0;
$offset = 0;
while (true)
{
$items = new ItemStatSetup($offset, CLISetup::SQL_BATCH, $itemClass, $ids, $applyTriggered, $enchStats, $this->relSpells);
if ($items->error)
break;
CLI::write('[stats] * batch #' . ++$i . ' (' . count($items->getFoundIDs()) . ')', CLI::LOG_BLANK, true, true);
CLI::write('[stats] * '.$name.' batch #' . ++$i . ' (' . count($items->getFoundIDs()) . ')', CLI::LOG_BLANK, true, true);
$offset = max($items->getFoundIDs());
$offset = max($items->getFoundIDs());
$items->writeStatsTable();
$items->writeStatsTable();
}
}
return true;