on('change:repeating_martialarts remove:repeating_martialarts change:repeating_weapon:repweapondef change:repeating_weapon:repweaponabi remove:repeating_weapon', TAS._fn(updateParry));
on('change:qc-parry', TAS._fn(updateParry));
async function updateParry(e) {
if (e.sourceType !== "player" && e.triggerName !== 'wound-penalty') {
if (debug >= 2) TAS.debug(`updateParry:: TRIGGER FROM SCRIPT => CANCEL`);
return;
}
if (debug >= 2) TAS.debug('updateParry:: e=' + JSON.stringify(e));
const setObj = await ParryUpdater.getUpdatedParryObj();
if (debug >= 2) TAS.debug('updateParry:: setObj=', setObj);
setAttrs(setObj);
}
class ParryUpdater {
#maIds;
#weaponIds;
constructor() {}
async getAttrToBeRetrieved(maIds, weaponIds) {
let time = new TimeCounter('ParryUpdater::getAttrToBeRetrieved');
if (debug === 3) TAS.debug(`ParryUpdater::getAttrToBeRetrieved maIds=${maIds}, weaponIds=${weaponIds}`);
this.#maIds = maIds || await getSectionIDsAsync('martialarts');
time.lap('after AWAIT getMA_ID');
this.#weaponIds = weaponIds || await getSectionIDsAsync('weapon');
time.lap(`after AWAIT getWEAP_ID, size=${this.#weaponIds.length}`);
TAS.debug(`ParryUpdate::getAttrToBeRetrieved #weaponIds=${JSON.stringify(this.#weaponIds)}`);
const attrList = ['qc', 'brawl', 'melee', 'dexterity', 'qc-parry', 'max-ma', ...defAddedAttrs];
time.lap('after constructing attrList');
this.#maIds.forEach(id => attrList.push(`repeating_martialarts_${id}_repmartialarts`));
time.lap('after forEach on MA');
this.#weaponIds.forEach(id => attrList.push(
`repeating_weapon_${id}_repweapondef`,
`repeating_weapon_${id}_repweaponabi`,
`repeating_weapon_${id}_repweaponparry`,
`repeating_weapon_${id}_repweaponparryspe`
));
time.lap('after forEach on WEAP');
maAttrsArray.forEach(attr => attrList.push(attr));
time.lap('after forEach on MA LIST');
return attrList;
}
updateObj(values, toBeUpdated = {}) {
const getFromUpdatedOrRetrieve = (attrStr) => (toBeUpdated && attrStr in toBeUpdated) ? toBeUpdated[attrStr] : values[attrStr];
let ma = 0;
for (const maName of maAttrsArray)
ma = Math.max(ma, Number(getFromUpdatedOrRetrieve(maName)));
const dex = Number(getFromUpdatedOrRetrieve('dexterity')),
brawl = Number(getFromUpdatedOrRetrieve('brawl')),
melee = Number(getFromUpdatedOrRetrieve('melee')),
qcParry = Number(getFromUpdatedOrRetrieve('qc-parry')),
isQc = Number(getFromUpdatedOrRetrieve('qc')),
finalObj = JSON.parse(JSON.stringify(toBeUpdated)),
addedDef = calcDefAddedAndSetOnslaughtApplied(values, finalObj),
correspondingTable = {'brawl': brawl, 'melee': melee};
for (const maName of maAttrsArray) correspondingTable[maName] = Number(getFromUpdatedOrRetrieve(maName));
if (debug >= 2) TAS.debug(`ParryUpdater:updateObj:: values=${JSON.stringify(values)}`);
ma = this.#maIds.reduce((acc, id) => Math.max(acc, Number(getFromUpdatedOrRetrieve(`repeating_martialarts_${id}_repmartialarts`))), ma);
if (debug === 3) TAS.debug(`ParryUpdater:updateObj:: Max MA=${ma}, isQc=${isQc}, qcParry=${qcParry}`);
if (debug === 3) TAS.debug('ParryUpdater:updateObj:: Unarmed Parry calc:', (isQc ? qcParry : 'Math.ceil(' + dex + ' + ' + brawl + ') / 2)'));
var newParry = (isQc ? qcParry : Math.ceil((dex + brawl) / 2));
if (debug === 3) TAS.debug('ParryUpdater:updateObj:: Unarmed Parry w/specialty calc:', (isQc ? qcParry+1 : 'Math.ceil(' + dex + ' + ' + brawl + ' + 1) / 2)'));
var newParrySpe = (isQc ? qcParry+1 : Math.ceil((dex + brawl + 1) / 2));
if (debug === 3) TAS.debug(`ParryUpdater:updateObj:: applying addedDef:${addedDef}`);
newParry += addedDef;
newParrySpe += addedDef;
if (debug === 3) TAS.debug('ParryUpdater:updateObj:: setAttrs!parry='+newParry+', parry-specialty='+newParrySpe);
verifyAndSetIfDifferent(values, finalObj, 'parry', newParry);
verifyAndSetIfDifferent(values, finalObj, 'parry-specialty', newParrySpe);
verifyAndSetIfDifferent(values, finalObj, 'max-ma', ma);
if (debug === 3) TAS.debug('ParryUpdater:updateObj:: Updating Weapon Parry value');
for (const id of this.#weaponIds) {
let def = getFromUpdatedOrRetrieve(`repeating_weapon_${id}_repweapondef`) || 0,
abi = getFromUpdatedOrRetrieve(`repeating_weapon_${id}_repweaponabi`) || 'brawl';
const weapParry = abi === 'noParry' ? -420 : Math.ceil((dex + (Object.keys(correspondingTable).includes(abi) ? correspondingTable[abi] : Number(abi)) ) / 2) + Number(def) + addedDef;
const weapParrySpe = abi === 'noParry' ? -420 : Math.ceil((dex + (Object.keys(correspondingTable).includes(abi) ? correspondingTable[abi] : Number(abi)) + 1) / 2) + Number(def) + addedDef;
verifyAndSetIfDifferent(values, finalObj, `repeating_weapon_${id}_repweaponparry`, weapParry);
verifyAndSetIfDifferent(values, finalObj, `repeating_weapon_${id}_repweaponparryspe`, weapParrySpe);
}
if (debug >= 2) TAS.debug('ParryUpdater:updateObj:: UPDATE WEAPONS PARRY', finalObj);
return finalObj;
}
async getUpdatedObj(toBeUpdated = {}) {
const values = await getAttrsAsync(await this.getAttrToBeRetrieved());
return this.updateObj(values, toBeUpdated);
}
static async getUpdatedParryObj(toBeUpdated = {}) {
return await new ParryUpdater().getUpdatedObj(toBeUpdated);
}
}