Seasonal indexes and types - RaiderIO/keystone.guru GitHub Wiki
Seasonal types
Affixes can sometimes be applied to certain enemies. Take the Infested affix, or the Inspiring affix. Certain hard-coded enemies have been marked with an affix and this needs to be displayed on the map. In order to mark these enemies, you can add a field called isInfested or isInspired but as the years go by, you're going to end up with dozens of columns that are only used once per season (most likely). In order to replace these columns, I've created a seasonal_type column. This is an enum which will allow you to select which seasonal effect is active on that enemy. Every time such a new affix pops up, the seasonal_type column will need to be amended to include it and a few places in the code need changing. In Enemy.php you need to add a new Seasonal type:
const SEASONAL_TYPE_BEGUILING = 'beguiling';
const SEASONAL_TYPE_AWAKENED = 'awakened';
const SEASONAL_TYPE_INSPIRING = 'inspiring';
const SEASONAL_TYPE_PRIDEFUL = 'prideful';
const SEASONAL_TYPE_TORMENTED = 'tormented';
const SEASONAL_TYPE_ENCRYPTED = 'encrypted';
const SEASONAL_TYPE_MDT_PLACEHOLDER = 'mdt_placeholder';
const SEASONAL_TYPE_SHROUDED = 'shrouded';
const SEASONAL_TYPE_SHROUDED_ZUL_GAMUX = 'shrouded_zul_gamux';
const SEASONAL_TYPE_NO_SHROUDED = 'no_shrouded';
const SEASONAL_TYPE_ALL = [
self::SEASONAL_TYPE_BEGUILING,
self::SEASONAL_TYPE_AWAKENED,
self::SEASONAL_TYPE_INSPIRING,
self::SEASONAL_TYPE_PRIDEFUL,
self::SEASONAL_TYPE_TORMENTED,
self::SEASONAL_TYPE_ENCRYPTED,
self::SEASONAL_TYPE_MDT_PLACEHOLDER,
self::SEASONAL_TYPE_SHROUDED,
self::SEASONAL_TYPE_SHROUDED_ZUL_GAMUX,
self::SEASONAL_TYPE_NO_SHROUDED,
];
In constants.js you need to add the new seasonal type:
let ENEMY_SEASONAL_TYPE_BEGUILING = 'beguiling';
let ENEMY_SEASONAL_TYPE_AWAKENED = 'awakened';
let ENEMY_SEASONAL_TYPE_INSPIRING = 'inspiring';
let ENEMY_SEASONAL_TYPE_PRIDEFUL = 'prideful';
let ENEMY_SEASONAL_TYPE_TORMENTED = 'tormented';
let ENEMY_SEASONAL_TYPE_ENCRYPTED = 'encrypted';
let ENEMY_SEASONAL_TYPE_MDT_PLACEHOLDER = 'mdt_placeholder';
let ENEMY_SEASONAL_TYPE_SHROUDED = 'shrouded';
let ENEMY_SEASONAL_TYPE_SHROUDED_ZUL_GAMUX = 'shrouded_zul_gamux';
let ENEMY_SEASONAL_TYPE_NO_SHROUDED = 'no_shrouded';
Then, in the map code, you can do something like the following to determine if an enemy has a seasonal type:
enemy.seasonal_type === ENEMY_SEASONAL_TYPE_INSPIRING && getState().getMapContext().hasAffix(AFFIX_INSPIRING)
Always include a check to determine if an affix is active on the current route. That way you don't get (in this case) Inspiring-specific code to run in a route that does not have the Inspiring affix.
Seasonal indices
To make matters worse, Blizzard has a tendency to put these seasonal type assignments on a rotation. That means that they have for example 3 different sets of Inspiring enemies that rotate to keep things fresher. This is where the seasonal index comes in. This allows you to tell the map "hey this enemy only is Inspired on week 1". The amount of rotations that are allowed are determined in the $season->presets field. So you can end up in the situation where the season has 12 affix groups, but a preset count of 3. That means that each "seasonal index" will be available 12/3=4 times every full rotation of the affix group list.
You can assign the seasonal index and seasonal type from the Mapping Version Edit page on each enemy that you edit.