diff --git a/analyze_gear.py b/analyze_gear.py
index 8be472b..c358406 100644
--- a/analyze_gear.py
+++ b/analyze_gear.py
@@ -67,6 +67,20 @@ def score_weapon(item):
s += get_num(stats.get('Block',0)) * 0.5
s += get_num(stats.get('Agility',0)) * 0.5
s -= get_num(stats.get('burden',0)) * 0.5
+ # Base weapon damage + elemental damage
+ s += get_num(stats.get('Weapon Damage',0)) * 0.30
+ for el in ['Fire','Cold','Elec','Wind','Holy','Dark','Ethereal','Elemental']:
+ s += get_num(stats.get('Elemental ' + el,0)) * 0.25
+ # Proc lines
+ for k, v in stats.items():
+ if k.startswith('Proc '):
+ pct = get_num(v)
+ pname = k.replace('Proc ','').lower()
+ if 'penetrated armor' in pname or 'armor' in pname: s += pct * 0.35
+ elif any(x in pname for x in ['stun','freeze','slow','paraly']): s += pct * 0.45
+ elif any(x in pname for x in ['bleeding','wound','poison','burn','shock']): s += pct * 0.25
+ elif 'weaken' in pname or 'impair' in pname: s += pct * 0.25
+ else: s += pct * 0.15
# Quality multiplier: higher tiers have better base damage
# q6=Magnificent, q5=Exquisite, q4=Superior, q3=Average, q2=Fair, q1=Crude
diff --git a/scripts/hv-unified.user.js b/scripts/hv-unified.user.js
index 3abd29f..a9a43b8 100644
--- a/scripts/hv-unified.user.js
+++ b/scripts/hv-unified.user.js
@@ -1,7 +1,7 @@
// ==UserScript==
// @name HV Unified
// @namespace hvunified
-// @version 0.15.2
+// @version 0.15.3
// @description HV Unified — battle automation, guidance, and UI enhancements for HentaiVerse
// @author GaboGG + Hermes
// @match *://*.hentaiverse.org/*
@@ -17,7 +17,7 @@
// CONFIG — default settings
// ═══════════════════════════════════════════════════════════════════════
-const VERSION = '0.15.2';
+const VERSION = '0.15.3';
const CFG = {
// — Battle automation
@@ -3512,6 +3512,41 @@ function parseEquipHTML(htmlStr) {
const ex = eq.querySelector('.ex');
if (ex) ex.querySelectorAll(':scope > div').forEach(parseRow);
+ // Direct-child rows of .eq — weapon damage + proc lines.
+ // e.g.
Penetrated Armor: 21.7% chance
+ // +708 Piercing Damage
+ Array.from(eq.children).forEach(child => {
+ if (child.classList && (child.classList.contains('eqt') || child.classList.contains('eqr')
+ || child.classList.contains('eqc') || child.classList.contains('ex') || child.classList.contains('ep'))) return;
+ const text = (child.textContent || '').trim();
+ if (!text) return;
+
+ // Proc line: "Name: 21.7% chance"
+ const procM = text.match(/^([A-Za-z][A-Za-z ]+):\s*([\d.]+%?\s*(?:chance|procs?)?)/);
+ if (procM && child.querySelector('span')) {
+ stats['Proc ' + procM[1].trim()] = procM[2].trim();
+ return;
+ }
+
+ // Weapon damage line: "+708 Piercing Damage"
+ const dmgM = text.match(/^\+([\d,]+)\s*([A-Za-z]+)\s*Damage$/);
+ if (dmgM) {
+ stats['Weapon Damage'] = parseInt(dmgM[1].replace(/,/g, ''));
+ stats['Damage Type'] = dmgM[2];
+ const title = child.getAttribute('title') || '';
+ const baseM = title.match(/Base:\s*(\d+)/i);
+ if (baseM) stats['Weapon Damage Base'] = parseInt(baseM[1]);
+ return;
+ }
+
+ // Elemental damage lines: "+25 Fire Damage" or "+30 Elec Damage"
+ const elemM = text.match(/^\+([\d,]+)\s*(Fire|Cold|Elec|Wind|Holy|Dark|Ethereal|Elemental)\s*(?:Damage|Strike)$/);
+ if (elemM) {
+ stats['Elemental ' + elemM[2]] = parseInt(elemM[1].replace(/,/g, ''));
+ return;
+ }
+ });
+
// Extra stat groups (.ep)
eq.querySelectorAll('.ep').forEach(g => {
g.querySelectorAll(':scope > div:not(:first-child)').forEach(parseRow);
@@ -3829,6 +3864,25 @@ function gearScoreWeapon(item) {
s += _num(st['Block']) * 0.5;
s += _num(st['Agility']) * 0.5;
s -= _num(st['burden']) * 0.5;
+ // Base weapon damage (e.g. "+708 Piercing Damage") — scales with quality
+ s += _num(st['Weapon Damage']) * 0.30;
+ // Elemental damage lines (e.g. "+25 Fire Damage", "+30 Elec Strike")
+ ['Fire', 'Cold', 'Elec', 'Wind', 'Holy', 'Dark', 'Ethereal', 'Elemental'].forEach(el => {
+ s += _num(st['Elemental ' + el]) * 0.25;
+ });
+ // Proc lines: elemental/status procs add value (e.g. "Proc Penetrated Armor: 21.7%")
+ let procBonus = 0;
+ Object.keys(st).forEach(k => {
+ if (!k.startsWith('Proc ')) return;
+ const pct = _num(st[k]);
+ const pname = k.replace('Proc ', '').toLowerCase();
+ if (pname.includes('penetrated armor') || pname.includes('armor')) procBonus += pct * 0.35;
+ else if (pname.includes('stun') || pname.includes('freeze') || pname.includes('slow') || pname.includes('paraly')) procBonus += pct * 0.45;
+ else if (pname.includes('bleeding') || pname.includes('wound') || pname.includes('poison') || pname.includes('burn') || pname.includes('shock')) procBonus += pct * 0.25;
+ else if (pname.includes('weaken') || pname.includes('impair')) procBonus += pct * 0.25;
+ else procBonus += pct * 0.15; // generic proc value
+ });
+ s += procBonus;
// Quality multiplier (q6=Magnificent, q5=Exquisite, q4=Superior)
s *= 0.8 + (quality * 0.12);
// Weapon type bonus
diff --git a/scripts/latest.user.js b/scripts/latest.user.js
index 3abd29f..a9a43b8 100644
--- a/scripts/latest.user.js
+++ b/scripts/latest.user.js
@@ -1,7 +1,7 @@
// ==UserScript==
// @name HV Unified
// @namespace hvunified
-// @version 0.15.2
+// @version 0.15.3
// @description HV Unified — battle automation, guidance, and UI enhancements for HentaiVerse
// @author GaboGG + Hermes
// @match *://*.hentaiverse.org/*
@@ -17,7 +17,7 @@
// CONFIG — default settings
// ═══════════════════════════════════════════════════════════════════════
-const VERSION = '0.15.2';
+const VERSION = '0.15.3';
const CFG = {
// — Battle automation
@@ -3512,6 +3512,41 @@ function parseEquipHTML(htmlStr) {
const ex = eq.querySelector('.ex');
if (ex) ex.querySelectorAll(':scope > div').forEach(parseRow);
+ // Direct-child rows of .eq — weapon damage + proc lines.
+ // e.g. Penetrated Armor: 21.7% chance
+ // +708 Piercing Damage
+ Array.from(eq.children).forEach(child => {
+ if (child.classList && (child.classList.contains('eqt') || child.classList.contains('eqr')
+ || child.classList.contains('eqc') || child.classList.contains('ex') || child.classList.contains('ep'))) return;
+ const text = (child.textContent || '').trim();
+ if (!text) return;
+
+ // Proc line: "Name: 21.7% chance"
+ const procM = text.match(/^([A-Za-z][A-Za-z ]+):\s*([\d.]+%?\s*(?:chance|procs?)?)/);
+ if (procM && child.querySelector('span')) {
+ stats['Proc ' + procM[1].trim()] = procM[2].trim();
+ return;
+ }
+
+ // Weapon damage line: "+708 Piercing Damage"
+ const dmgM = text.match(/^\+([\d,]+)\s*([A-Za-z]+)\s*Damage$/);
+ if (dmgM) {
+ stats['Weapon Damage'] = parseInt(dmgM[1].replace(/,/g, ''));
+ stats['Damage Type'] = dmgM[2];
+ const title = child.getAttribute('title') || '';
+ const baseM = title.match(/Base:\s*(\d+)/i);
+ if (baseM) stats['Weapon Damage Base'] = parseInt(baseM[1]);
+ return;
+ }
+
+ // Elemental damage lines: "+25 Fire Damage" or "+30 Elec Damage"
+ const elemM = text.match(/^\+([\d,]+)\s*(Fire|Cold|Elec|Wind|Holy|Dark|Ethereal|Elemental)\s*(?:Damage|Strike)$/);
+ if (elemM) {
+ stats['Elemental ' + elemM[2]] = parseInt(elemM[1].replace(/,/g, ''));
+ return;
+ }
+ });
+
// Extra stat groups (.ep)
eq.querySelectorAll('.ep').forEach(g => {
g.querySelectorAll(':scope > div:not(:first-child)').forEach(parseRow);
@@ -3829,6 +3864,25 @@ function gearScoreWeapon(item) {
s += _num(st['Block']) * 0.5;
s += _num(st['Agility']) * 0.5;
s -= _num(st['burden']) * 0.5;
+ // Base weapon damage (e.g. "+708 Piercing Damage") — scales with quality
+ s += _num(st['Weapon Damage']) * 0.30;
+ // Elemental damage lines (e.g. "+25 Fire Damage", "+30 Elec Strike")
+ ['Fire', 'Cold', 'Elec', 'Wind', 'Holy', 'Dark', 'Ethereal', 'Elemental'].forEach(el => {
+ s += _num(st['Elemental ' + el]) * 0.25;
+ });
+ // Proc lines: elemental/status procs add value (e.g. "Proc Penetrated Armor: 21.7%")
+ let procBonus = 0;
+ Object.keys(st).forEach(k => {
+ if (!k.startsWith('Proc ')) return;
+ const pct = _num(st[k]);
+ const pname = k.replace('Proc ', '').toLowerCase();
+ if (pname.includes('penetrated armor') || pname.includes('armor')) procBonus += pct * 0.35;
+ else if (pname.includes('stun') || pname.includes('freeze') || pname.includes('slow') || pname.includes('paraly')) procBonus += pct * 0.45;
+ else if (pname.includes('bleeding') || pname.includes('wound') || pname.includes('poison') || pname.includes('burn') || pname.includes('shock')) procBonus += pct * 0.25;
+ else if (pname.includes('weaken') || pname.includes('impair')) procBonus += pct * 0.25;
+ else procBonus += pct * 0.15; // generic proc value
+ });
+ s += procBonus;
// Quality multiplier (q6=Magnificent, q5=Exquisite, q4=Superior)
s *= 0.8 + (quality * 0.12);
// Weapon type bonus
diff --git a/src/config.js b/src/config.js
index aeb9668..f985738 100644
--- a/src/config.js
+++ b/src/config.js
@@ -2,7 +2,7 @@
// CONFIG — default settings
// ═══════════════════════════════════════════════════════════════════════
-const VERSION = '0.15.2';
+const VERSION = '0.15.3';
const CFG = {
// — Battle automation
diff --git a/src/gear-analysis.js b/src/gear-analysis.js
index 913f298..70fbd1e 100644
--- a/src/gear-analysis.js
+++ b/src/gear-analysis.js
@@ -45,6 +45,25 @@ function gearScoreWeapon(item) {
s += _num(st['Block']) * 0.5;
s += _num(st['Agility']) * 0.5;
s -= _num(st['burden']) * 0.5;
+ // Base weapon damage (e.g. "+708 Piercing Damage") — scales with quality
+ s += _num(st['Weapon Damage']) * 0.30;
+ // Elemental damage lines (e.g. "+25 Fire Damage", "+30 Elec Strike")
+ ['Fire', 'Cold', 'Elec', 'Wind', 'Holy', 'Dark', 'Ethereal', 'Elemental'].forEach(el => {
+ s += _num(st['Elemental ' + el]) * 0.25;
+ });
+ // Proc lines: elemental/status procs add value (e.g. "Proc Penetrated Armor: 21.7%")
+ let procBonus = 0;
+ Object.keys(st).forEach(k => {
+ if (!k.startsWith('Proc ')) return;
+ const pct = _num(st[k]);
+ const pname = k.replace('Proc ', '').toLowerCase();
+ if (pname.includes('penetrated armor') || pname.includes('armor')) procBonus += pct * 0.35;
+ else if (pname.includes('stun') || pname.includes('freeze') || pname.includes('slow') || pname.includes('paraly')) procBonus += pct * 0.45;
+ else if (pname.includes('bleeding') || pname.includes('wound') || pname.includes('poison') || pname.includes('burn') || pname.includes('shock')) procBonus += pct * 0.25;
+ else if (pname.includes('weaken') || pname.includes('impair')) procBonus += pct * 0.25;
+ else procBonus += pct * 0.15; // generic proc value
+ });
+ s += procBonus;
// Quality multiplier (q6=Magnificent, q5=Exquisite, q4=Superior)
s *= 0.8 + (quality * 0.12);
// Weapon type bonus
diff --git a/src/gear-scraper.js b/src/gear-scraper.js
index 83b9f37..fbf82cc 100644
--- a/src/gear-scraper.js
+++ b/src/gear-scraper.js
@@ -117,6 +117,41 @@ function parseEquipHTML(htmlStr) {
const ex = eq.querySelector('.ex');
if (ex) ex.querySelectorAll(':scope > div').forEach(parseRow);
+ // Direct-child rows of .eq — weapon damage + proc lines.
+ // e.g. Penetrated Armor: 21.7% chance
+ // +708 Piercing Damage
+ Array.from(eq.children).forEach(child => {
+ if (child.classList && (child.classList.contains('eqt') || child.classList.contains('eqr')
+ || child.classList.contains('eqc') || child.classList.contains('ex') || child.classList.contains('ep'))) return;
+ const text = (child.textContent || '').trim();
+ if (!text) return;
+
+ // Proc line: "Name: 21.7% chance"
+ const procM = text.match(/^([A-Za-z][A-Za-z ]+):\s*([\d.]+%?\s*(?:chance|procs?)?)/);
+ if (procM && child.querySelector('span')) {
+ stats['Proc ' + procM[1].trim()] = procM[2].trim();
+ return;
+ }
+
+ // Weapon damage line: "+708 Piercing Damage"
+ const dmgM = text.match(/^\+([\d,]+)\s*([A-Za-z]+)\s*Damage$/);
+ if (dmgM) {
+ stats['Weapon Damage'] = parseInt(dmgM[1].replace(/,/g, ''));
+ stats['Damage Type'] = dmgM[2];
+ const title = child.getAttribute('title') || '';
+ const baseM = title.match(/Base:\s*(\d+)/i);
+ if (baseM) stats['Weapon Damage Base'] = parseInt(baseM[1]);
+ return;
+ }
+
+ // Elemental damage lines: "+25 Fire Damage" or "+30 Elec Damage"
+ const elemM = text.match(/^\+([\d,]+)\s*(Fire|Cold|Elec|Wind|Holy|Dark|Ethereal|Elemental)\s*(?:Damage|Strike)$/);
+ if (elemM) {
+ stats['Elemental ' + elemM[2]] = parseInt(elemM[1].replace(/,/g, ''));
+ return;
+ }
+ });
+
// Extra stat groups (.ep)
eq.querySelectorAll('.ep').forEach(g => {
g.querySelectorAll(':scope > div:not(:first-child)').forEach(parseRow);
diff --git a/src/header.user.js b/src/header.user.js
index 325ec74..21e8bce 100644
--- a/src/header.user.js
+++ b/src/header.user.js
@@ -1,7 +1,7 @@
// ==UserScript==
// @name HV Unified
// @namespace hvunified
-// @version 0.15.2
+// @version 0.15.3
// @description HV Unified — battle automation, guidance, and UI enhancements for HentaiVerse
// @author GaboGG + Hermes
// @match *://*.hentaiverse.org/*