v0.15.4 - Elemental Strikes parsed + scored per wiki (Void Strike, etc.)
From EHWiki Detailed_Equip_Characteristics + Equipment_Basics: - Elemental strikes are 'X Strike (Y%)' lines (Void/Fire/Cold/Elec/ Wind/Holy/Dark), separate hit for ~50% of physical damage, max 2 strikes + Void Strike - Ethereal weapons deal Void damage (+523 Void Damage), prefixes: Ethereal→Void, Fiery→Fire, Arctic→Cold, Shocking→Elec, Tempestuous→Wind, Hallowed→Holy, Demonic→Dark - Weapon procs by type: Piercing→Penetrated Armor (Estoc/Rapier), Crushing→Stun (Mace/Club), Slashing→Bleeding Wound (Longsword/ Katana/Shortsword/Axe/Wakizashi) Parser now captures: - stats['Strike <Elem>'] = chance% (e.g. 'Strike Void': 50) - stats['Weapon Damage'] for Void too (+523 Void Damage) Scorer adds expected strike damage (chance/100 × 0.5 × weapon dmg) weighted same as base damage. Type bonuses updated to match real procs (Stun 1.15x > Bleeding 1.10x, Rapier 1.20x like Estoc 1.25x). So your lottery Peerless Ethereal Rapier (+523 Void, Void Strike 50%) now scores properly. Note: re-scrape after update for Strike fields.
This commit is contained in:
parent
f993014a46
commit
589ed7e34c
7 changed files with 101 additions and 54 deletions
|
|
@ -67,10 +67,14 @@ 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
|
||||
# Base weapon damage + elemental strikes
|
||||
wd = get_num(stats.get('Weapon Damage',0))
|
||||
s += wd * 0.30
|
||||
for el in ['Fire','Cold','Elec','Wind','Holy','Dark','Void','Ethereal']:
|
||||
chance = get_num(stats.get('Strike ' + el,0))
|
||||
if chance > 0:
|
||||
expected = (chance / 100) * 0.5 * wd
|
||||
s += expected * 0.30 if expected > 0 else chance * 0.15
|
||||
# Proc lines
|
||||
for k, v in stats.items():
|
||||
if k.startswith('Proc '):
|
||||
|
|
@ -87,18 +91,16 @@ def score_weapon(item):
|
|||
quality_mult = 0.8 + (quality * 0.12) # q4=1.28x, q5=1.40x, q6=1.52x
|
||||
s *= quality_mult
|
||||
|
||||
# Weapon type bonus: Estoc has Penetrated Armor proc (armor break)
|
||||
# Longsword has Weaken proc (damage debuff on enemies)
|
||||
# Weapon type bonus (wiki procs: Piercing→Penetrated Armor, Crushing→Stun,
|
||||
# Slashing→Bleeding Wound; Estoc=2H Penetrated Armor is the 2H physical build's core)
|
||||
if 'estoc' in name_lower:
|
||||
s *= 1.25 # Estoc's Penetrated Armor is the defining proc for 2H physical builds
|
||||
elif 'longsword' in name_lower:
|
||||
s *= 1.10 # Weaken proc is decent but not as impactful
|
||||
elif 'great mace' in name_lower:
|
||||
s *= 0.90 # No armor pen, lower utility
|
||||
elif 'club' in name_lower:
|
||||
s *= 0.85
|
||||
elif 'axe' in name_lower:
|
||||
s *= 0.90
|
||||
s *= 1.25
|
||||
elif 'rapier' in name_lower:
|
||||
s *= 1.20 # 1H Penetrated Armor
|
||||
elif any(k in name_lower for k in ['longsword','katana','shortsword','axe','wakizashi']):
|
||||
s *= 1.10 # Bleeding Wound
|
||||
elif any(k in name_lower for k in ['great mace','club','mace']):
|
||||
s *= 1.15 # Stun
|
||||
|
||||
return s
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// ==UserScript==
|
||||
// @name HV Unified
|
||||
// @namespace hvunified
|
||||
// @version 0.15.3
|
||||
// @version 0.15.4
|
||||
// @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.3';
|
||||
const VERSION = '0.15.4';
|
||||
|
||||
const CFG = {
|
||||
// — Battle automation
|
||||
|
|
@ -3528,7 +3528,16 @@ function parseEquipHTML(htmlStr) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Weapon damage line: "+708 Piercing Damage"
|
||||
// Elemental Strike line (wiki: "X Strike (Y%)" — e.g. "Void Strike (50%)")
|
||||
// Additional ~50%-of-physical-damage hit; max 2 strikes + Void Strike.
|
||||
const strikeM = text.match(/^([A-Za-z]+)\s+Strike\s*\(\s*(\d+)%\s*\)$/);
|
||||
if (strikeM) {
|
||||
stats['Strike ' + strikeM[1]] = parseInt(strikeM[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
// Weapon damage line: "+523 Void Damage" / "+708 Piercing Damage"
|
||||
// Base type can be Slashing/Crushing/Piercing, or Void for Ethereal.
|
||||
const dmgM = text.match(/^\+([\d,]+)\s*([A-Za-z]+)\s*Damage$/);
|
||||
if (dmgM) {
|
||||
stats['Weapon Damage'] = parseInt(dmgM[1].replace(/,/g, ''));
|
||||
|
|
@ -3864,11 +3873,17 @@ 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;
|
||||
// Base weapon damage (e.g. "+708 Piercing Damage", "+523 Void Damage") — scales with quality
|
||||
const wd = _num(st['Weapon Damage']);
|
||||
s += wd * 0.30;
|
||||
// Elemental Strikes (wiki: "X Strike (Y%)" — separate hit for ~50% of physical damage)
|
||||
// Expected damage = chance% × 0.5 × weapon damage. Weight same as base damage (0.30).
|
||||
['Fire', 'Cold', 'Elec', 'Wind', 'Holy', 'Dark', 'Void', 'Ethereal'].forEach(el => {
|
||||
const chance = _num(st['Strike ' + el]);
|
||||
if (chance > 0) {
|
||||
const expected = (chance / 100) * 0.5 * wd;
|
||||
s += expected > 0 ? expected * 0.30 : chance * 0.15;
|
||||
}
|
||||
});
|
||||
// Proc lines: elemental/status procs add value (e.g. "Proc Penetrated Armor: 21.7%")
|
||||
let procBonus = 0;
|
||||
|
|
@ -3885,12 +3900,12 @@ function gearScoreWeapon(item) {
|
|||
s += procBonus;
|
||||
// Quality multiplier (q6=Magnificent, q5=Exquisite, q4=Superior)
|
||||
s *= 0.8 + (quality * 0.12);
|
||||
// Weapon type bonus
|
||||
// Weapon type bonus (wiki procs: Piercing→Penetrated Armor, Crushing→Stun,
|
||||
// Slashing→Bleeding Wound; Estoc=2H Penetrated Armor is the 2H physical build's core)
|
||||
if (name.includes('estoc')) s *= 1.25;
|
||||
else if (name.includes('longsword')) s *= 1.10;
|
||||
else if (name.includes('great mace')) s *= 0.90;
|
||||
else if (name.includes('club')) s *= 0.85;
|
||||
else if (name.includes('axe')) s *= 0.90;
|
||||
else if (name.includes('rapier')) s *= 1.20; // 1H Penetrated Armor
|
||||
else if (name.includes('longsword') || name.includes('katana') || name.includes('shortsword') || name.includes('axe') || name.includes('wakizashi')) s *= 1.10; // Bleeding Wound
|
||||
else if (name.includes('great mace') || name.includes('club') || name.includes('mace')) s *= 1.15; // Stun
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// ==UserScript==
|
||||
// @name HV Unified
|
||||
// @namespace hvunified
|
||||
// @version 0.15.3
|
||||
// @version 0.15.4
|
||||
// @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.3';
|
||||
const VERSION = '0.15.4';
|
||||
|
||||
const CFG = {
|
||||
// — Battle automation
|
||||
|
|
@ -3528,7 +3528,16 @@ function parseEquipHTML(htmlStr) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Weapon damage line: "+708 Piercing Damage"
|
||||
// Elemental Strike line (wiki: "X Strike (Y%)" — e.g. "Void Strike (50%)")
|
||||
// Additional ~50%-of-physical-damage hit; max 2 strikes + Void Strike.
|
||||
const strikeM = text.match(/^([A-Za-z]+)\s+Strike\s*\(\s*(\d+)%\s*\)$/);
|
||||
if (strikeM) {
|
||||
stats['Strike ' + strikeM[1]] = parseInt(strikeM[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
// Weapon damage line: "+523 Void Damage" / "+708 Piercing Damage"
|
||||
// Base type can be Slashing/Crushing/Piercing, or Void for Ethereal.
|
||||
const dmgM = text.match(/^\+([\d,]+)\s*([A-Za-z]+)\s*Damage$/);
|
||||
if (dmgM) {
|
||||
stats['Weapon Damage'] = parseInt(dmgM[1].replace(/,/g, ''));
|
||||
|
|
@ -3864,11 +3873,17 @@ 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;
|
||||
// Base weapon damage (e.g. "+708 Piercing Damage", "+523 Void Damage") — scales with quality
|
||||
const wd = _num(st['Weapon Damage']);
|
||||
s += wd * 0.30;
|
||||
// Elemental Strikes (wiki: "X Strike (Y%)" — separate hit for ~50% of physical damage)
|
||||
// Expected damage = chance% × 0.5 × weapon damage. Weight same as base damage (0.30).
|
||||
['Fire', 'Cold', 'Elec', 'Wind', 'Holy', 'Dark', 'Void', 'Ethereal'].forEach(el => {
|
||||
const chance = _num(st['Strike ' + el]);
|
||||
if (chance > 0) {
|
||||
const expected = (chance / 100) * 0.5 * wd;
|
||||
s += expected > 0 ? expected * 0.30 : chance * 0.15;
|
||||
}
|
||||
});
|
||||
// Proc lines: elemental/status procs add value (e.g. "Proc Penetrated Armor: 21.7%")
|
||||
let procBonus = 0;
|
||||
|
|
@ -3885,12 +3900,12 @@ function gearScoreWeapon(item) {
|
|||
s += procBonus;
|
||||
// Quality multiplier (q6=Magnificent, q5=Exquisite, q4=Superior)
|
||||
s *= 0.8 + (quality * 0.12);
|
||||
// Weapon type bonus
|
||||
// Weapon type bonus (wiki procs: Piercing→Penetrated Armor, Crushing→Stun,
|
||||
// Slashing→Bleeding Wound; Estoc=2H Penetrated Armor is the 2H physical build's core)
|
||||
if (name.includes('estoc')) s *= 1.25;
|
||||
else if (name.includes('longsword')) s *= 1.10;
|
||||
else if (name.includes('great mace')) s *= 0.90;
|
||||
else if (name.includes('club')) s *= 0.85;
|
||||
else if (name.includes('axe')) s *= 0.90;
|
||||
else if (name.includes('rapier')) s *= 1.20; // 1H Penetrated Armor
|
||||
else if (name.includes('longsword') || name.includes('katana') || name.includes('shortsword') || name.includes('axe') || name.includes('wakizashi')) s *= 1.10; // Bleeding Wound
|
||||
else if (name.includes('great mace') || name.includes('club') || name.includes('mace')) s *= 1.15; // Stun
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// CONFIG — default settings
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
|
||||
const VERSION = '0.15.3';
|
||||
const VERSION = '0.15.4';
|
||||
|
||||
const CFG = {
|
||||
// — Battle automation
|
||||
|
|
|
|||
|
|
@ -45,11 +45,17 @@ 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;
|
||||
// Base weapon damage (e.g. "+708 Piercing Damage", "+523 Void Damage") — scales with quality
|
||||
const wd = _num(st['Weapon Damage']);
|
||||
s += wd * 0.30;
|
||||
// Elemental Strikes (wiki: "X Strike (Y%)" — separate hit for ~50% of physical damage)
|
||||
// Expected damage = chance% × 0.5 × weapon damage. Weight same as base damage (0.30).
|
||||
['Fire', 'Cold', 'Elec', 'Wind', 'Holy', 'Dark', 'Void', 'Ethereal'].forEach(el => {
|
||||
const chance = _num(st['Strike ' + el]);
|
||||
if (chance > 0) {
|
||||
const expected = (chance / 100) * 0.5 * wd;
|
||||
s += expected > 0 ? expected * 0.30 : chance * 0.15;
|
||||
}
|
||||
});
|
||||
// Proc lines: elemental/status procs add value (e.g. "Proc Penetrated Armor: 21.7%")
|
||||
let procBonus = 0;
|
||||
|
|
@ -66,12 +72,12 @@ function gearScoreWeapon(item) {
|
|||
s += procBonus;
|
||||
// Quality multiplier (q6=Magnificent, q5=Exquisite, q4=Superior)
|
||||
s *= 0.8 + (quality * 0.12);
|
||||
// Weapon type bonus
|
||||
// Weapon type bonus (wiki procs: Piercing→Penetrated Armor, Crushing→Stun,
|
||||
// Slashing→Bleeding Wound; Estoc=2H Penetrated Armor is the 2H physical build's core)
|
||||
if (name.includes('estoc')) s *= 1.25;
|
||||
else if (name.includes('longsword')) s *= 1.10;
|
||||
else if (name.includes('great mace')) s *= 0.90;
|
||||
else if (name.includes('club')) s *= 0.85;
|
||||
else if (name.includes('axe')) s *= 0.90;
|
||||
else if (name.includes('rapier')) s *= 1.20; // 1H Penetrated Armor
|
||||
else if (name.includes('longsword') || name.includes('katana') || name.includes('shortsword') || name.includes('axe') || name.includes('wakizashi')) s *= 1.10; // Bleeding Wound
|
||||
else if (name.includes('great mace') || name.includes('club') || name.includes('mace')) s *= 1.15; // Stun
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -133,7 +133,16 @@ function parseEquipHTML(htmlStr) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Weapon damage line: "+708 Piercing Damage"
|
||||
// Elemental Strike line (wiki: "X Strike (Y%)" — e.g. "Void Strike (50%)")
|
||||
// Additional ~50%-of-physical-damage hit; max 2 strikes + Void Strike.
|
||||
const strikeM = text.match(/^([A-Za-z]+)\s+Strike\s*\(\s*(\d+)%\s*\)$/);
|
||||
if (strikeM) {
|
||||
stats['Strike ' + strikeM[1]] = parseInt(strikeM[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
// Weapon damage line: "+523 Void Damage" / "+708 Piercing Damage"
|
||||
// Base type can be Slashing/Crushing/Piercing, or Void for Ethereal.
|
||||
const dmgM = text.match(/^\+([\d,]+)\s*([A-Za-z]+)\s*Damage$/);
|
||||
if (dmgM) {
|
||||
stats['Weapon Damage'] = parseInt(dmgM[1].replace(/,/g, ''));
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// ==UserScript==
|
||||
// @name HV Unified
|
||||
// @namespace hvunified
|
||||
// @version 0.15.3
|
||||
// @version 0.15.4
|
||||
// @description HV Unified — battle automation, guidance, and UI enhancements for HentaiVerse
|
||||
// @author GaboGG + Hermes
|
||||
// @match *://*.hentaiverse.org/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue