define([
'js/misc/statTranslations',
'ui/templates/tooltipItem/buildTooltip/stringifyStatValue'
], function (
statTranslations,
stringifyStatValue
) {
let item = null;
let compare = null;
let shiftDown = null;
let equipErrors = null;
const init = (_item, _compare, _shiftDown, _equipErrors) => {
item = _item;
compare = _compare;
shiftDown = _shiftDown;
equipErrors = _equipErrors;
};
const lineBuilders = {
div: (className, children) => {
if (!children)
return null;
if (children.join)
children = children.join('');
if (!children.length)
return null;
return `
${children}
`;
},
name: () => {
let itemName = item.name;
if (item.quantity > 1)
itemName += ' x' + item.quantity;
return itemName;
},
type: () => {
if (!item.type || item.type === item.name)
return null;
return item.type;
},
power: () => {
if (!item.power)
return null;
return (new Array(item.power + 1)).join('+');
},
implicitStats: () => {
if (!item.implicitStats)
return null;
const tempImplicitStats = $.extend(true, [], item.implicitStats);
if (compare && shiftDown && !item.eq) {
const compareImplicitStats = (compare.implicitStats || []);
tempImplicitStats.forEach(s => {
const { stat, value } = s;
const f = compareImplicitStats.find(c => c.stat === stat);
if (!f) {
s.value = `+${value}`;
return;
}
const delta = value - f.value;
if (delta > 0)
s.value = `+${delta}`;
else if (delta < 0)
s.value = delta;
});
compareImplicitStats.forEach(s => {
if (tempImplicitStats.some(f => f.stat === s.stat))
return;
tempImplicitStats.push({
stat: s.stat,
value: -s.value
});
});
}
const html = tempImplicitStats
.map(({ stat, value }) => {
let statName = statTranslations.translate(stat);
const prettyValue = stringifyStatValue(stat, value);
let rowClass = '';
if (compare) {
if (prettyValue.indexOf('-') > -1)
rowClass = 'loseStat';
else if (prettyValue.indexOf('+') > -1)
rowClass = 'gainStat';
}
return `${prettyValue} ${statName}
`;
})
.join('');
const result = (
lineBuilders.div('space', ' ') +
html
);
return result;
},
stats: () => {
const tempStats = $.extend(true, {}, item.stats);
const enchantedStats = item.enchantedStats || {};
if (compare && shiftDown) {
if (!item.eq) {
const compareStats = compare.stats;
for (let s in tempStats) {
if (compareStats[s]) {
const delta = tempStats[s] - compareStats[s];
if (delta > 0)
tempStats[s] = '+' + delta;
else if (delta < 0)
tempStats[s] = delta;
} else
tempStats[s] = '+' + tempStats[s];
}
for (let s in compareStats) {
if (!tempStats[s])
tempStats[s] = -compareStats[s];
}
}
} else {
Object.keys(tempStats).forEach(s => {
if (enchantedStats[s]) {
tempStats[s] -= enchantedStats[s];
if (tempStats[s] <= 0)
delete tempStats[s];
tempStats['_' + s] = enchantedStats[s];
}
});
}
const html = Object.keys(tempStats)
.map(s => {
const isEnchanted = (s[0] === '_');
let statName = s;
if (isEnchanted)
statName = statName.substr(1);
const prettyValue = stringifyStatValue(statName, tempStats[s]);
statName = statTranslations.translate(statName);
let rowClass = '';
if (compare) {
if (prettyValue.indexOf('-') > -1)
rowClass = 'loseStat';
else if (prettyValue.indexOf('+') > -1)
rowClass = 'gainStat';
}
if (isEnchanted)
rowClass += ' enchanted';
return `${prettyValue} ${statName}
`;
})
.sort((a, b) => {
return (a.replace(' enchanted', '').length - b.replace(' enchanted', '').length);
})
.sort((a, b) => {
if (a.indexOf('enchanted') > -1 && b.indexOf('enchanted') === -1)
return 1;
else if (a.indexOf('enchanted') === -1 && b.indexOf('enchanted') > -1)
return -1;
return 0;
})
.join('');
if (!html)
return null;
const result = (
lineBuilders.div('space', ' ') +
lineBuilders.div('line', ' ') +
lineBuilders.div('smallSpace', ' ') +
html +
lineBuilders.div('smallSpace', ' ') +
lineBuilders.div('line', ' ')
);
return result;
},
effects: () => {
if (!item.effects || !item.effects.length || !item.effects[0].text || item.type === 'mtx')
return null;
let html = '';
item.effects.forEach((e, i) => {
html += e.text;
if (i < item.effects.length - 1)
html += '
';
});
const result = (
lineBuilders.div('space', ' ') +
lineBuilders.div('line', ' ') +
lineBuilders.div('smallSpace', ' ') +
html +
lineBuilders.div('smallSpace', ' ') +
lineBuilders.div('line', ' ')
);
return result;
},
material: () => {
if (item.material)
return 'crafting material';
},
quest: () => {
if (item.quest)
return 'quest item';
},
spellName: () => {
if (!item.spell || item.ability)
return null;
return (
lineBuilders.div('space', ' ') +
lineBuilders.div(`spellName q${item.spell.quality}`, item.spell.name)
);
},
damage: () => {
if (!item.spell || !item.spell.values)
return null;
const abilityValues = Object.entries(item.spell.values)
.map(([k, v]) => {
if (!compare || !shiftDown)
return `${k}: ${v}
`;
let delta = v - compare.spell.values[k];
// adjust by EPSILON to handle float point imprecision, otherwise 3.15 - 2 = 1.14 or 2 - 3.15 = -1.14
// have to move away from zero by EPSILON, not a simple add
if (delta >= 0)
delta += Number.EPSILON;
else
delta -= Number.EPSILON;
delta = ~~((delta) * 100) / 100;
let rowClass = '';
if (delta > 0) {
rowClass = 'gainDamage';
delta = '+' + delta;
} else if (delta < 0)
rowClass = 'loseDamage';
return `${k}: ${delta}
`;
})
.join('');
return abilityValues;
},
requires: (className, children) => {
if (!item.requires && !item.level && (!item.factions || !item.factions.length))
return null;
if (equipErrors.length)
className += ' high-level';
return (
lineBuilders.div('space', ' ') +
lineBuilders.div(className, 'requires')
);
},
requireLevel: className => {
if (!item.level)
return null;
if (equipErrors.includes('level'))
className += ' high-level';
const level = item.level.push ? `${item.level[0]} - ${item.level[1]}` : item.level;
return lineBuilders.div(className, `level: ${level}`);
},
requireStats: className => {
if (!item.requires || !item.requires[0])
return null;
if (equipErrors.includes('stats'))
className += ' high-level';
let html = `${item.requires[0].stat}: ${item.requires[0].value}`;
return lineBuilders.div(className, html);
},
requireFaction: () => {
if (!item.factions)
return null;
let htmlFactions = '';
item.factions.forEach((f, i) => {
let htmlF = f.name + ': ' + f.tierName;
if (f.noEquip)
htmlF = '' + htmlF + '';
htmlFactions += htmlF;
if (i < item.factions.length - 1)
htmlFactions += '
';
});
return htmlFactions;
},
worth: () => {
if (!item.worthText)
return null;
return (
lineBuilders.div('space', ' ') +
`value: ${item.worthText}`
);
},
info: () => {
if (!item.slot)
return null;
let text = null;
if (isMobile && compare && !shiftDown)
text = 'tap again to compare';
else if (!shiftDown && compare)
text = '[shift] to compare';
if (!text)
return null;
return (
lineBuilders.div('space', ' ') +
text
);
},
description: () => {
if (!item.description)
return null;
return (
lineBuilders.div('space', ' ') +
item.description
);
},
cd: () => {
if (!item.cd)
return null;
return `cooldown: ${item.cd}`;
},
uses: () => {
if (!item.uses)
return null;
return `uses: ${item.uses}`;
}
};
return {
init,
lineBuilders
};
});