forked from xziino/ff14-mitigator
Analyse+Planer: Phys/Mag-DR fix (Feint/Addle) + Plenary Indulgence (WHM)
- ffxiv-data.js: abilityDr() für typabhängige DR — Feint 10% phys/5% mag, Addle 10% mag/5% phys - analysis.js + planner.js: abilityDr() in simulateDrMultiplier() und Debuff-Tooltip - analysis.php: Plenary Indulgence (statusId 1001219 "Confession", 10% DR, WHM) - ffxiv-data.js: Plenary Indulgence in JOB_ABILITIES/ABILITY_DR/MITIG_ICONS - Action.json: Eintrag 7433 (recast 600 = 60s) für Gantt-Diagramm - Icon: plenary-indulgence.png von XIVAPI - cache.php: v11 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
3726a35a72
commit
4003060699
@ -88,6 +88,7 @@ const MITIGATION_ABILITIES = [
|
|||||||
'Dark Missionary' => ['dr' => 10, 'buffType' => 'buff', 'statusId' => 1001894, 'extraAbilityGameID' => 16471],
|
'Dark Missionary' => ['dr' => 10, 'buffType' => 'buff', 'statusId' => 1001894, 'extraAbilityGameID' => 16471],
|
||||||
'Heart of Light' => ['dr' => 10, 'buffType' => 'buff', 'statusId' => 1001839, 'extraAbilityGameID' => 16160],
|
'Heart of Light' => ['dr' => 10, 'buffType' => 'buff', 'statusId' => 1001839, 'extraAbilityGameID' => 16160],
|
||||||
'Temperance' => ['dr' => 10, 'buffType' => 'buff', 'statusId' => 1001873, 'extraAbilityGameID' => 16536],
|
'Temperance' => ['dr' => 10, 'buffType' => 'buff', 'statusId' => 1001873, 'extraAbilityGameID' => 16536],
|
||||||
|
'Plenary Indulgence' => ['dr' => 10, 'buffType' => 'buff', 'statusId' => 1001219, 'extraAbilityGameID' => 7433], // FFLogs: "Confession"
|
||||||
'Aquaveil' => ['dr' => 15, 'buffType' => 'buff', 'statusId' => 1002708, 'extraAbilityGameID' => 25861], // Personal, WHM auf Ziel
|
'Aquaveil' => ['dr' => 15, 'buffType' => 'buff', 'statusId' => 1002708, 'extraAbilityGameID' => 25861], // Personal, WHM auf Ziel
|
||||||
'Sacred Soil' => ['dr' => 10, 'buffType' => 'buff', 'statusId' => 1001944, 'extraAbilityGameID' => 188],
|
'Sacred Soil' => ['dr' => 10, 'buffType' => 'buff', 'statusId' => 1001944, 'extraAbilityGameID' => 188],
|
||||||
'Expedient' => ['dr' => 10, 'buffType' => 'buff', 'statusId' => 1002711, 'extraAbilityGameID' => 25868], // FFLogs: "Desperate Measures"
|
'Expedient' => ['dr' => 10, 'buffType' => 'buff', 'statusId' => 1002711, 'extraAbilityGameID' => 25868], // FFLogs: "Desperate Measures"
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
const CACHED_LOG_DIR = __DIR__ . '/../cached_logs';
|
const CACHED_LOG_DIR = __DIR__ . '/../cached_logs';
|
||||||
const CACHED_LOG_VERSION = 'v9';
|
const CACHED_LOG_VERSION = 'v11';
|
||||||
|
|
||||||
function cache_language(string $language): string {
|
function cache_language(string $language): string {
|
||||||
$language = strtolower(trim($language));
|
$language = strtolower(trim($language));
|
||||||
|
|||||||
BIN
assets/icons/mitigation/plenary-indulgence.png
Normal file
BIN
assets/icons/mitigation/plenary-indulgence.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
@ -419,6 +419,18 @@
|
|||||||
"icon": "https://xivapi.com/i/003000/003087_hr1.png",
|
"icon": "https://xivapi.com/i/003000/003087_hr1.png",
|
||||||
"shield": null
|
"shield": null
|
||||||
},
|
},
|
||||||
|
"7433": {
|
||||||
|
"cast": 0,
|
||||||
|
"recast": 600,
|
||||||
|
"names": {
|
||||||
|
"en": "Plenary Indulgence",
|
||||||
|
"de": "Vollkommener Ablass",
|
||||||
|
"fr": "Indulgence plénière",
|
||||||
|
"jp": "インドゥルゲンティア"
|
||||||
|
},
|
||||||
|
"icon": null,
|
||||||
|
"shield": null
|
||||||
|
},
|
||||||
"16536": {
|
"16536": {
|
||||||
"cast": 0,
|
"cast": 0,
|
||||||
"recast": 1200,
|
"recast": 1200,
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
(function () {
|
(function () {
|
||||||
const { MITIG_ICONS, JOB_ABBR, ABILITY_JOBS, JOB_ROLE, abilityTypeIsPhysical, abilityTypeIsMagical } = window.FF14_DATA;
|
const { MITIG_ICONS, JOB_ABBR, ABILITY_JOBS, JOB_ROLE, abilityTypeIsPhysical, abilityTypeIsMagical, abilityDr } = window.FF14_DATA;
|
||||||
|
|
||||||
function dmgTypeBadge(abilityType) {
|
function dmgTypeBadge(abilityType) {
|
||||||
if (abilityType == null) return '';
|
if (abilityType == null) return '';
|
||||||
@ -612,7 +612,8 @@
|
|||||||
].map(m => {
|
].map(m => {
|
||||||
const iconSrc = mitigationIcon(m);
|
const iconSrc = mitigationIcon(m);
|
||||||
if (!iconSrc) return '';
|
if (!iconSrc) return '';
|
||||||
const dr = m.dr > 0 ? ` −${m.dr}%` : '';
|
const drPct = Math.round(abilityDr(m.name, ev.abilityType) * 100) || m.dr || 0;
|
||||||
|
const dr = drPct > 0 ? ` −${drPct}%` : '';
|
||||||
const jobAbbr = m.sourcePlayerType ? (JOB_ABBR[m.sourcePlayerType] ?? '') : '';
|
const jobAbbr = m.sourcePlayerType ? (JOB_ABBR[m.sourcePlayerType] ?? '') : '';
|
||||||
const label = jobAbbr ? `${jobAbbr} · ${m.name}` : m.name;
|
const label = jobAbbr ? `${jobAbbr} · ${m.name}` : m.name;
|
||||||
return m.missing
|
return m.missing
|
||||||
|
|||||||
@ -10,6 +10,13 @@
|
|||||||
function abilityTypeIsPhysical(type) { return (parseInt(type) & ABILITY_TYPE_PHYSICAL) !== 0; }
|
function abilityTypeIsPhysical(type) { return (parseInt(type) & ABILITY_TYPE_PHYSICAL) !== 0; }
|
||||||
function abilityTypeIsMagical(type) { return (parseInt(type) & ABILITY_TYPE_MAGICAL) !== 0; }
|
function abilityTypeIsMagical(type) { return (parseInt(type) & ABILITY_TYPE_MAGICAL) !== 0; }
|
||||||
|
|
||||||
|
// Type-aware DR: Feint 10% phys / 5% mag, Addle 10% mag / 5% phys
|
||||||
|
function abilityDr(abilityName, abilityType) {
|
||||||
|
if (abilityName === 'Feint') return abilityTypeIsPhysical(abilityType) ? 0.10 : 0.05;
|
||||||
|
if (abilityName === 'Addle') return abilityTypeIsMagical(abilityType) ? 0.10 : 0.05;
|
||||||
|
return ABILITY_DR[abilityName] ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
const JOB_FROM_TYPE = {
|
const JOB_FROM_TYPE = {
|
||||||
'Paladin': 'PLD', 'Warrior': 'WAR', 'DarkKnight': 'DRK', 'Gunbreaker': 'GNB',
|
'Paladin': 'PLD', 'Warrior': 'WAR', 'DarkKnight': 'DRK', 'Gunbreaker': 'GNB',
|
||||||
'WhiteMage': 'WHM', 'Scholar': 'SCH', 'Astrologian': 'AST', 'Sage': 'SGE',
|
'WhiteMage': 'WHM', 'Scholar': 'SCH', 'Astrologian': 'AST', 'Sage': 'SGE',
|
||||||
@ -89,6 +96,7 @@
|
|||||||
],
|
],
|
||||||
'WHM': [
|
'WHM': [
|
||||||
{ name: 'Temperance', buffType: 'buff' },
|
{ name: 'Temperance', buffType: 'buff' },
|
||||||
|
{ name: 'Plenary Indulgence', buffType: 'buff', extraAbilityGameID: 7433, duration: 10 },
|
||||||
{ name: 'Aquaveil', buffType: 'buff', extraAbilityGameID: 25861, duration: 8 }, // Personal, WHM auf Ziel
|
{ name: 'Aquaveil', buffType: 'buff', extraAbilityGameID: 25861, duration: 8 }, // Personal, WHM auf Ziel
|
||||||
{ name: 'Divine Benison', buffType: 'shield', extraAbilityGameID: 7432, duration: 15 },
|
{ name: 'Divine Benison', buffType: 'shield', extraAbilityGameID: 7432, duration: 15 },
|
||||||
{ name: 'Divine Caress', buffType: 'shield' },
|
{ name: 'Divine Caress', buffType: 'shield' },
|
||||||
@ -177,7 +185,7 @@
|
|||||||
'Heart of Light': 'GNB', 'Superbolide': 'GNB', 'Nebula': 'GNB',
|
'Heart of Light': 'GNB', 'Superbolide': 'GNB', 'Nebula': 'GNB',
|
||||||
'Great Nebula': 'GNB', 'Camouflage': 'GNB', 'Heart of Stone': 'GNB',
|
'Great Nebula': 'GNB', 'Camouflage': 'GNB', 'Heart of Stone': 'GNB',
|
||||||
'Heart of Corundum': 'GNB', 'Clarity of Corundum': 'GNB',
|
'Heart of Corundum': 'GNB', 'Clarity of Corundum': 'GNB',
|
||||||
'Temperance': 'WHM', 'Aquaveil': 'WHM', 'Divine Benison': 'WHM', 'Divine Caress': 'WHM',
|
'Temperance': 'WHM', 'Plenary Indulgence': 'WHM', 'Aquaveil': 'WHM', 'Divine Benison': 'WHM', 'Divine Caress': 'WHM',
|
||||||
'Sacred Soil': 'SCH', 'Expedient': 'SCH', 'Fey Illumination': 'SCH',
|
'Sacred Soil': 'SCH', 'Expedient': 'SCH', 'Fey Illumination': 'SCH',
|
||||||
'Galvanize': 'SCH', 'Seraphic Veil': 'SCH', 'Catalyze': 'SCH',
|
'Galvanize': 'SCH', 'Seraphic Veil': 'SCH', 'Catalyze': 'SCH',
|
||||||
'Collective Unconscious': 'AST', 'Exaltation': 'AST', 'Neutral Sect': 'AST',
|
'Collective Unconscious': 'AST', 'Exaltation': 'AST', 'Neutral Sect': 'AST',
|
||||||
@ -204,6 +212,7 @@
|
|||||||
'Dark Missionary': 'assets/icons/mitigation/dark-missionary.png',
|
'Dark Missionary': 'assets/icons/mitigation/dark-missionary.png',
|
||||||
'Heart of Light': 'assets/icons/mitigation/heart-of-light.png',
|
'Heart of Light': 'assets/icons/mitigation/heart-of-light.png',
|
||||||
'Temperance': 'assets/icons/mitigation/temperance.png',
|
'Temperance': 'assets/icons/mitigation/temperance.png',
|
||||||
|
'Plenary Indulgence': 'assets/icons/mitigation/plenary-indulgence.png',
|
||||||
'Sacred Soil': 'assets/icons/mitigation/sacred-soil.png',
|
'Sacred Soil': 'assets/icons/mitigation/sacred-soil.png',
|
||||||
'Expedient': 'assets/icons/mitigation/expedient.png',
|
'Expedient': 'assets/icons/mitigation/expedient.png',
|
||||||
'Fey Illumination': 'assets/icons/mitigation/fey-illumination.png',
|
'Fey Illumination': 'assets/icons/mitigation/fey-illumination.png',
|
||||||
@ -258,6 +267,7 @@
|
|||||||
'Dark Missionary': 0.10,
|
'Dark Missionary': 0.10,
|
||||||
'Heart of Light': 0.10,
|
'Heart of Light': 0.10,
|
||||||
'Temperance': 0.10,
|
'Temperance': 0.10,
|
||||||
|
'Plenary Indulgence': 0.10,
|
||||||
'Sacred Soil': 0.10,
|
'Sacred Soil': 0.10,
|
||||||
'Expedient': 0.10,
|
'Expedient': 0.10,
|
||||||
'Collective Unconscious': 0.10,
|
'Collective Unconscious': 0.10,
|
||||||
@ -323,5 +333,6 @@
|
|||||||
ABILITY_TYPE_MAGICAL,
|
ABILITY_TYPE_MAGICAL,
|
||||||
abilityTypeIsPhysical,
|
abilityTypeIsPhysical,
|
||||||
abilityTypeIsMagical,
|
abilityTypeIsMagical,
|
||||||
|
abilityDr,
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@ -651,7 +651,7 @@ function simulateDrMultiplier(mechanic, assignments = mechanic.assignments ?? []
|
|||||||
if (a.buffType === 'shield') continue;
|
if (a.buffType === 'shield') continue;
|
||||||
// Persönliche Mitigation nur bei Tankbustern einrechnen
|
// Persönliche Mitigation nur bei Tankbustern einrechnen
|
||||||
if (!isTankbuster && TIMELINE_PERSONAL_ABILITIES.has(a.ability)) continue;
|
if (!isTankbuster && TIMELINE_PERSONAL_ABILITIES.has(a.ability)) continue;
|
||||||
mult *= (1 - (ABILITY_DR[a.ability] ?? 0));
|
mult *= (1 - abilityDr(a.ability, mechanic.abilityType));
|
||||||
}
|
}
|
||||||
return mult;
|
return mult;
|
||||||
}
|
}
|
||||||
@ -2340,6 +2340,7 @@ const {
|
|||||||
TANK_JOBS,
|
TANK_JOBS,
|
||||||
abilityTypeIsPhysical,
|
abilityTypeIsPhysical,
|
||||||
abilityTypeIsMagical,
|
abilityTypeIsMagical,
|
||||||
|
abilityDr,
|
||||||
} = window.FF14_DATA;
|
} = window.FF14_DATA;
|
||||||
|
|
||||||
function dmgTypeBadge(abilityType) {
|
function dmgTypeBadge(abilityType) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user