Skip to content

Commit

Permalink
feat: Effective healing and absorptions
Browse files Browse the repository at this point in the history
For #191
  • Loading branch information
Sundava committed Feb 25, 2022
1 parent f646b5a commit 15cd99d
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 61 deletions.
89 changes: 47 additions & 42 deletions overlay/css/table.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,48 +18,53 @@
flex-grow: 10;
flex-basis: 0%;
}
.flex-column-i-class { width: var(--_i-class)rem; } /* replace-hack only */
.flex-column-i-rank { width: var(--_i-rank)rem; }
.flex-column-i-owner { width: var(--_i-owner)rem; }
.flex-column-i-name { width: var(--_i-name)rem; }
.flex-column-deal-total { width: var(--_deal-total)rem; }
.flex-column-deal-per-second { width: var(--_deal-per_second)rem; }
.flex-column-deal-pct { width: var(--_deal-pct)rem; }
.flex-column-deal-failure { width: var(--_deal-failure)rem; }
.flex-column-deal-accuracy { width: var(--_deal-accuracy)rem; }
.flex-column-deal-swing { width: var(--_deal-swing)rem; }
.flex-column-deal-miss { width: var(--_deal-miss)rem; }
.flex-column-deal-hitfail { width: var(--_deal-hitfail)rem; }
.flex-column-deal-critical { width: var(--_deal-critical)rem; }
.flex-column-deal-direct { width: var(--_deal-direct)rem; }
.flex-column-deal-crit-direct { width: var(--_deal-crit_direct)rem; }
.flex-column-deal-crittypes { width: var(--_deal-crittypes)rem; }
.flex-column-deal-critpcts { width: var(--_deal-critpcts)rem; }
.flex-column-deal-max { width: var(--_deal-max)rem; }
.flex-column-deal-maxhit { width: var(--_deal-maxhit)rem; }
.flex-column-deal-maxskill { width: var(--_deal-maxskill)rem; }
.flex-column-deal-last10 { width: var(--_deal-last10)rem; }
.flex-column-deal-last30 { width: var(--_deal-last30)rem; }
.flex-column-deal-last60 { width: var(--_deal-last60)rem; }
.flex-column-deal-last180 { width: var(--_deal-last180)rem; }
.flex-column-tank-damage { width: var(--_tank-damage)rem; }
.flex-column-tank-parry { width: var(--_tank-parry)rem; }
.flex-column-tank-heal { width: var(--_tank-heal)rem; }
.flex-column-tank-block { width: var(--_tank-block)rem; }
.flex-column-tank-threat-delta { width: var(--_tank-threat_delta)rem; }
.flex-column-heal-per-second { width: var(--_heal-per_second)rem; }
.flex-column-heal-pct { width: var(--_heal-pct)rem; }
.flex-column-heal-total { width: var(--_heal-total)rem; }
.flex-column-heal-swing { width: var(--_heal-swing)rem; }
.flex-column-heal-over { width: var(--_heal-over)rem; }
.flex-column-heal-cure { width: var(--_heal-cure)rem; }
.flex-column-heal-critical { width: var(--_heal-critical)rem; }
.flex-column-heal-max { width: var(--_heal-max)rem; }
.flex-column-heal-maxhit { width: var(--_heal-maxhit)rem; }
.flex-column-heal-maxskill { width: var(--_heal-maxskill)rem; }
.flex-column-etc-powerdrain { width: var(--_etc-powerdrain)rem; }
.flex-column-etc-death { width: var(--_etc-death)rem; }
.flex-column-etc-powerheal { width: var(--_etc-powerheal)rem; }
.flex-column-i-class { width: var(--_i-class)rem; } /* replace-hack only */
.flex-column-i-rank { width: var(--_i-rank)rem; }
.flex-column-i-owner { width: var(--_i-owner)rem; }
.flex-column-i-name { width: var(--_i-name)rem; }
.flex-column-deal-total { width: var(--_deal-total)rem; }
.flex-column-deal-per-second { width: var(--_deal-per_second)rem; }
.flex-column-deal-pct { width: var(--_deal-pct)rem; }
.flex-column-deal-failure { width: var(--_deal-failure)rem; }
.flex-column-deal-accuracy { width: var(--_deal-accuracy)rem; }
.flex-column-deal-swing { width: var(--_deal-swing)rem; }
.flex-column-deal-miss { width: var(--_deal-miss)rem; }
.flex-column-deal-hitfail { width: var(--_deal-hitfail)rem; }
.flex-column-deal-critical { width: var(--_deal-critical)rem; }
.flex-column-deal-direct { width: var(--_deal-direct)rem; }
.flex-column-deal-crit-direct { width: var(--_deal-crit_direct)rem; }
.flex-column-deal-crittypes { width: var(--_deal-crittypes)rem; }
.flex-column-deal-critpcts { width: var(--_deal-critpcts)rem; }
.flex-column-deal-max { width: var(--_deal-max)rem; }
.flex-column-deal-maxhit { width: var(--_deal-maxhit)rem; }
.flex-column-deal-maxskill { width: var(--_deal-maxskill)rem; }
.flex-column-deal-last10 { width: var(--_deal-last10)rem; }
.flex-column-deal-last30 { width: var(--_deal-last30)rem; }
.flex-column-deal-last60 { width: var(--_deal-last60)rem; }
.flex-column-deal-last180 { width: var(--_deal-last180)rem; }
.flex-column-tank-damage { width: var(--_tank-damage)rem; }
.flex-column-tank-parry { width: var(--_tank-parry)rem; }
.flex-column-tank-heal { width: var(--_tank-heal)rem; }
.flex-column-tank-block { width: var(--_tank-block)rem; }
.flex-column-tank-threat-delta { width: var(--_tank-threat_delta)rem; }
.flex-column-heal-per-second { width: var(--_heal-per_second)rem; }
.flex-column-heal-pct { width: var(--_heal-pct)rem; }
.flex-column-heal-total { width: var(--_heal-total)rem; }
.flex-column-heal-effective-per-second { width: var(--_heal-effective_per_second)rem; }
.flex-column-heal-effective-pct { width: var(--_heal-effective_pct)rem; }
.flex-column-heal-effective-total { width: var(--_heal-effective_total)rem; }
.flex-column-heal-absorb-pct { width: var(--_heal-absorb_pct)rem; }
.flex-column-heal-absorb-total { width: var(--_heal-absorb_total)rem; }
.flex-column-heal-swing { width: var(--_heal-swing)rem; }
.flex-column-heal-over { width: var(--_heal-over)rem; }
.flex-column-heal-cure { width: var(--_heal-cure)rem; }
.flex-column-heal-critical { width: var(--_heal-critical)rem; }
.flex-column-heal-max { width: var(--_heal-max)rem; }
.flex-column-heal-maxhit { width: var(--_heal-maxhit)rem; }
.flex-column-heal-maxskill { width: var(--_heal-maxskill)rem; }
.flex-column-etc-powerdrain { width: var(--_etc-powerdrain)rem; }
.flex-column-etc-death { width: var(--_etc-death)rem; }
.flex-column-etc-powerheal { width: var(--_etc-powerheal)rem; }

.pet-merged .flex-column-i-owner {
display: none !important;
Expand Down
38 changes: 30 additions & 8 deletions overlay/lib/listen.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
SORTABLE[k] = o.v || o
})


class Data {

constructor(data) {
Expand All @@ -25,9 +26,9 @@

update(data) {
this.isActive = data.isActive
this.calculateHealingValues(data)
this.header = data.Encounter
this.data = toArray(data.Combatant)
this.calculateMax(data.Combatant)
}

get(sort, merged) {
Expand Down Expand Up @@ -93,21 +94,42 @@
}

sort(key, target) {
let d = (('+-'.indexOf(key[0]))+1 || 1) * 2 - 3
let k = SORTABLE[key.substr('+-'.indexOf(key[0]) >= 0)]
;(target || this.data).sort((a, b) => (pFloat(a[k]) - pFloat(b[k])) * d)
let order = (('+-'.indexOf(key[0]))+1 || 1) * 2 - 3 // 1:asc, -1:desc
let sort_by = SORTABLE[key.substr('+-'.indexOf(key[0]) >= 0)]

if (typeof sort_by == "string") {
(target || this.data).sort((a, b) => (pFloat(a[sort_by]) - pFloat(b[sort_by])) * order)
} else if (typeof sort_by == "function") {
(target || this.data).sort((a, b) => (sort_by(a) - sort_by(b)) * order)
}
if(target) return target
}

// Calculate additional healing values and store them in the Combatant or Encounter
calculateHealingValues(data) {
let rhealing_effective = 0;
let rabsorb_healing = 0;
for (let i in data.Combatant) {
let player = data.Combatant[i];
let effective = parseInt(player.healed) - parseInt(player.overHeal);
// Inject the calculated effective healing into the player data, while we're at it
player.effective_healing = effective;
rhealing_effective += effective;
rabsorb_healing += parseInt(player.damageShield)
}
// Inject into the Encounter data for later use
data.Encounter.rhealing_effective = rhealing_effective
data.Encounter.rabsorb_healing = rabsorb_healing
}

calculateMax(combatant) {
let max = {}

for(let k in SORTABLE) {
let v = SORTABLE[k]
max[k] = Math.max.apply(
Math, Object.keys(combatant).map(_ => combatant[_][v])
)
if (typeof v == "string")
max[k] = Math.max.apply(Math, Object.keys(combatant).map(_ => combatant[_][v]))
else if (typeof v == "function")
max[k] = Math.max.apply(Math, combatant.map(_ => v(_)))
}

return max
Expand Down
21 changes: 11 additions & 10 deletions overlay/lib/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@
if(isYou(o.name, this.config.format.myname)) {
playerRank = o.rank
}
table.appendChild(this.template.render(o, max))
table.appendChild(this.template.render(o, d, data.header, max))
}

// footer (rdps, rhps)
Expand Down Expand Up @@ -211,14 +211,15 @@
this.owners = window.config && window.config.get('format.myname')
}

_value(v, data) {
if(typeof v === 'string')
_value(v, data, players, encounter) {
if(typeof v === 'string'){
return data[v]
}
else if(typeof v === 'function')
return v(data)
return v(data, players, encounter)
}

part(c, data) {
part(c, data, players, encounter) {
let el = document.createElement('span')
let text = ''
let classes = `flex-column flex-column-${sanitize(c)}`
Expand All @@ -234,7 +235,7 @@
if(typeof col === 'string') {
text = data[col]
} else {
text = this._value(col.v, data)
text = this._value(col.v, data, players, encounter)

if(typeof col.f === 'function')
text = col.f(text, window.config.get())
Expand All @@ -251,7 +252,7 @@
return el
}

render(data, max) {
render(data, players, encounter, max) {
let el = document.createElement('li')
let k = this.tab.sort.substr('+-'.indexOf(this.tab.sort[0]) >= 0)
let gaugeBy = resolveDotIndex(COLUMN_INDEX, k)
Expand All @@ -260,20 +261,20 @@
if(gaugeBy.v) {
gaugeBy = gaugeBy.v
}

if(data !== null) {
let cls = sanitize(COLUMN_INDEX.i.class.v(data))
el.classList.add('class-' + (cls || 'unknown'))
el.classList.toggle('me', isYou(data.name, this.owners))

let width = this._value(gaugeBy, data) / max[this.tab.sort] * 100
let width = this._value(gaugeBy, data, players, encounter) / max[this.tab.sort] * 100

el.innerHTML = `<span class="gauge" style="width:${width}%"></span>`
} else {
el.id = 'header'
}

for(let section of this.tab.col) {
el.appendChild(this.part(section, data))
el.appendChild(this.part(section, data, players, encounter))
}

return el
Expand Down
5 changes: 5 additions & 0 deletions share/lang/cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,11 @@
"per_second": ["HPS", "每秒治疗量"],
"pct": ["H%", "治疗比率%"],
"total": ["总治疗", "总治疗量"],
"effective_per_second" : ["Eff. HPS", "per Second effective"],
"effective_pct" : ["Eff. H%", "Effective healing %"],
"effective_total": ["Eff. H.", "Effective"],
"absorb_pct": ["Abs. %", "Absorption %"],
"absorb_total": ["Abs. H.", "Absorption"],
"over": ["过量%", "过量治疗"],
"swing": ["次数", "治疗次数"],
"critical": ["H暴%", "治疗暴击率%"],
Expand Down
5 changes: 5 additions & 0 deletions share/lang/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,11 @@
"per_second": ["HPS", "Heilung pro Sekunde"],
"pct": ["H%", "% der Gesamtheilung"],
"total": ["H.Ges.", "Gesamtheilung"],
"effective_per_second" : ["Eff. HPS", "per Second effective"],
"effective_pct" : ["Eff. H%", "Effective healing %"],
"effective_total": ["Eff. H.", "Effective"],
"absorb_pct": ["Abs. %", "Absorption %"],
"absorb_total": ["Abs. H.", "Absorption"],
"over": ["OvrH", "Overheal"],
"swing": ["Heilungen", "Anzahl der Heilungen"],
"critical": ["HCrit", "Kritischer Trefferchance"],
Expand Down
5 changes: 5 additions & 0 deletions share/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,11 @@
"per_second": ["HPS", "per Second"],
"pct": ["H%", "Heal %"],
"total": ["H.Tot", "Total"],
"effective_per_second" : ["Eff. HPS", "per Second effective"],
"effective_pct" : ["Eff. H%", "Effective healing %"],
"effective_total": ["Eff. H.", "Effective"],
"absorb_pct": ["Abs. %", "Absorption %"],
"absorb_total": ["Abs. H.", "Absorption"],
"over": ["OvH%", "Overheal"],
"swing": ["Swing", "Swings"],
"critical": ["HCrit", "Critical%"],
Expand Down
7 changes: 6 additions & 1 deletion share/lang/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,13 @@
"heal": {
"_": "Soin",
"per_second": ["HPS", "Par seconde"],
"pct": ["H%", "Soin %"],
"pct": ["H%", "% des soins"],
"total": ["H.Tot", "Total"],
"effective_per_second" : ["Eff. HPS", "Par seconde effectif"],
"effective_pct" : ["Eff. H%", "% des soins effectifs"],
"effective_total": ["Eff. H.", "Effectif"],
"absorb_pct": ["Abs. %", "% d'absorption"],
"absorb_total": ["Abs. H.", "Absorption"],
"over": ["OvH%", "Overheal"],
"swing": ["Esquive", "Esquives"],
"critical": ["HCrit", "Critique%"],
Expand Down
5 changes: 5 additions & 0 deletions share/lang/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,11 @@
"per_second": ["HPS", "HPS"],
"pct": ["H%", "寄与率"],
"total": ["H合", "合計"],
"effective_per_second" : ["Eff. HPS", "per Second effective"],
"effective_pct" : ["Eff. H%", "Effective healing %"],
"effective_total": ["Eff. H.", "Effective"],
"absorb_pct": ["Abs. %", "Absorption %"],
"absorb_total": ["Abs. H.", "Absorption"],
"over": ["Ovr+", "オーバーヒール"],
"swing": ["Swing", "詠唱回数"],
"critical": ["HCrit", "Critical%"],
Expand Down
5 changes: 5 additions & 0 deletions share/lang/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,11 @@
"per_second": ["HPS", "HPS"],
"pct": ["힐%", "기여율"],
"total": ["힐 합계", "합계"],
"effective_per_second" : ["Eff. HPS", "per Second effective"],
"effective_pct" : ["Eff. H%", "Effective healing %"],
"effective_total": ["Eff. H.", "Effective"],
"absorb_pct": ["Abs. %", "Absorption %"],
"absorb_total": ["Abs. H.", "Absorption"],
"over": ["Ovr+", "오버힐"],
"swing": ["타격", "타격 횟수"],
"critical": ["+극대", "극대화 비율"],
Expand Down
46 changes: 46 additions & 0 deletions share/lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ const CONFIG_DEFAULT = {
'_heal-per_second': 3,
'_heal-pct': 2,
'_heal-total': 4,
'_heal-effective_per_second': 3,
'_heal-effective_pct': 3,
'_heal-effective_total': 4,
'_heal-absorb_pct': 3,
'_heal-absorb_total': 4,
'_heal-swing': 2,
'_heal-over': 2,
'_heal-cure': 2,
Expand Down Expand Up @@ -230,6 +235,9 @@ const COLUMN_SORTABLE = [
'tank.heal',
'heal.per_second',
'heal.total',
'heal.effective_per_second',
'heal.effective_total',
'heal.absorb_total',
'-etc.death'
]
const COLUMN_MERGEABLE = [
Expand Down Expand Up @@ -515,6 +523,44 @@ const COLUMN_INDEX = {
v: _ => _['OverHealPct'],
f: _ => _ && _.replace? _.replace('%', '<small>%</small>') : '---'
},
effective_per_second: {
v: _ => {
return _['enchps'] * (1 - parseInt(_['OverHealPct']) / 100)
},
f: (_, conf) => {
_ = pFloat(_)
return isNaN(_)?
'0'
: formatDps(_, conf.format, 'hps')
}
},
effective_pct: {
v: (_, players, encounter) => {
// Calculated and injected during Data.update()
return Math.round(_.effective_healing / encounter.rhealing_effective * 100)
},
f: _ => {
if(isNaN(_)) return '---'
else if(_ >= 100) return '100'
else return _ + '<small>%</small>'
}
},
effective_total: {
v: _ => _.effective_healing, // Calculated and injected Data.update()
f: (_, conf) => formatDps(_, conf.format, 'damage', true)
},
absorb_pct: {
v: (_, players, encounter) => Math.round(_['damageShield'] / encounter.rabsorb_healing * 100),
f: _ => {
if(isNaN(_)) return '---'
else if(_ >= 100) return '100'
else return _ + '<small>%</small>'
}
},
absorb_total: {
v: 'damageShield',
f:(_, conf) => formatDps(_, conf.format, 'damage', true)
},
swing: 'heals',
critical: {
v: _ => (parseInt(_.critheals) || 0) / (parseInt(_.heals) || 1) * 100,
Expand Down

0 comments on commit 15cd99d

Please sign in to comment.