more personals

This commit is contained in:
Akurosia Kamo 2026-05-24 11:45:46 +02:00
parent 90fcbb69a5
commit e8863d83a5
3 changed files with 189 additions and 68 deletions

View File

@ -8,7 +8,8 @@
"fr": "Sentinelle",
"jp": "センチネル"
},
"icon": "https://xivapi.com/i/000000/000151_hr1.png"
"icon": "https://xivapi.com/i/000000/000151_hr1.png",
"shield": null
},
"22": {
"cast": 0,
@ -19,7 +20,8 @@
"fr": "Forteresse",
"jp": "ブルワーク"
},
"icon": "https://xivapi.com/i/000000/000167_hr1.png"
"icon": "https://xivapi.com/i/000000/000167_hr1.png",
"shield": null
},
"30": {
"cast": 0,
@ -30,7 +32,8 @@
"fr": "Invincible",
"jp": "インビンシブル"
},
"icon": "https://xivapi.com/i/002000/002502_hr1.png"
"icon": "https://xivapi.com/i/002000/002502_hr1.png",
"shield": null
},
"40": {
"cast": 0,
@ -41,7 +44,8 @@
"fr": "Frisson de la bataille",
"jp": "スリル・オブ・バトル"
},
"icon": "https://xivapi.com/i/000000/000263_hr1.png"
"icon": "https://xivapi.com/i/000000/000263_hr1.png",
"shield": null
},
"43": {
"cast": 0,
@ -52,7 +56,8 @@
"fr": "Holmgang",
"jp": "ホルムギャング"
},
"icon": "https://xivapi.com/i/000000/000266_hr1.png"
"icon": "https://xivapi.com/i/000000/000266_hr1.png",
"shield": null
},
"44": {
"cast": 0,
@ -63,7 +68,8 @@
"fr": "Représailles",
"jp": "ヴェンジェンス"
},
"icon": "https://xivapi.com/i/000000/000267_hr1.png"
"icon": "https://xivapi.com/i/000000/000267_hr1.png",
"shield": null
},
"157": {
"cast": 0,
@ -74,7 +80,8 @@
"fr": "Barrière de mana",
"jp": "マバリア"
},
"icon": "https://xivapi.com/i/000000/000463_hr1.png"
"icon": "https://xivapi.com/i/000000/000463_hr1.png",
"shield": "30% max HP"
},
"185": {
"cast": 20,
@ -85,7 +92,8 @@
"fr": "Traité du réconfort",
"jp": "鼓舞激励の策"
},
"icon": "https://xivapi.com/i/002000/002801_hr1.png"
"icon": "https://xivapi.com/i/002000/002801_hr1.png",
"shield": null
},
"188": {
"cast": 0,
@ -96,7 +104,8 @@
"fr": "Dogme de survie",
"jp": "野戦治療の陣"
},
"icon": "https://xivapi.com/i/002000/002804_hr1.png"
"icon": "https://xivapi.com/i/002000/002804_hr1.png",
"shield": null
},
"2241": {
"cast": 0,
@ -107,7 +116,8 @@
"fr": "Décalage d'ombre",
"jp": "残影"
},
"icon": "https://xivapi.com/i/000000/000607_hr1.png"
"icon": "https://xivapi.com/i/000000/000607_hr1.png",
"shield": "20% max HP"
},
"3540": {
"cast": 0,
@ -118,7 +128,8 @@
"fr": "Voile divin",
"jp": "ディヴァインヴェール"
},
"icon": "https://xivapi.com/i/002000/002508_hr1.png"
"icon": "https://xivapi.com/i/002000/002508_hr1.png",
"shield": "10% max HP"
},
"3551": {
"cast": 0,
@ -129,7 +140,8 @@
"fr": "Intuition pure",
"jp": "原初の直感"
},
"icon": "https://xivapi.com/i/002000/002559_hr1.png"
"icon": "https://xivapi.com/i/002000/002559_hr1.png",
"shield": null
},
"3613": {
"cast": 0,
@ -140,7 +152,8 @@
"fr": "Inconscient collectif",
"jp": "運命の輪"
},
"icon": "https://xivapi.com/i/003000/003140_hr1.png"
"icon": "https://xivapi.com/i/003000/003140_hr1.png",
"shield": null
},
"3634": {
"cast": 0,
@ -151,7 +164,8 @@
"fr": "Esprit ténébreux",
"jp": "ダークマインド"
},
"icon": "https://xivapi.com/i/003000/003076_hr1.png"
"icon": "https://xivapi.com/i/003000/003076_hr1.png",
"shield": null
},
"3636": {
"cast": 0,
@ -162,7 +176,8 @@
"fr": "Mur d'ombre",
"jp": "シャドウウォール"
},
"icon": "https://xivapi.com/i/003000/003075_hr1.png"
"icon": "https://xivapi.com/i/003000/003075_hr1.png",
"shield": null
},
"3638": {
"cast": 0,
@ -173,7 +188,8 @@
"fr": "Mort-vivant",
"jp": "リビングデッド"
},
"icon": "https://xivapi.com/i/003000/003077_hr1.png"
"icon": "https://xivapi.com/i/003000/003077_hr1.png",
"shield": null
},
"7382": {
"cast": 0,
@ -184,7 +200,8 @@
"fr": "Intervention",
"jp": "インターベンション"
},
"icon": "https://xivapi.com/i/002000/002512_hr1.png"
"icon": "https://xivapi.com/i/002000/002512_hr1.png",
"shield": null
},
"7385": {
"cast": 0,
@ -195,7 +212,8 @@
"fr": "Passe d'armes",
"jp": "パッセージ・オブ・アームズ"
},
"icon": "https://xivapi.com/i/002000/002515_hr1.png"
"icon": "https://xivapi.com/i/002000/002515_hr1.png",
"shield": null
},
"7388": {
"cast": 0,
@ -206,7 +224,8 @@
"fr": "Débarrassage",
"jp": "シェイクオフ"
},
"icon": "https://xivapi.com/i/002000/002563_hr1.png"
"icon": "https://xivapi.com/i/002000/002563_hr1.png",
"shield": "15% max HP"
},
"7393": {
"cast": 0,
@ -217,7 +236,8 @@
"fr": "Nuit noirissime",
"jp": "ブラックナイト"
},
"icon": "https://xivapi.com/i/003000/003081_hr1.png"
"icon": "https://xivapi.com/i/003000/003081_hr1.png",
"shield": "25% max HP"
},
"7394": {
"cast": 0,
@ -228,7 +248,8 @@
"fr": "Énigme de la terre",
"jp": "金剛の極意"
},
"icon": "https://xivapi.com/i/002000/002537_hr1.png"
"icon": "https://xivapi.com/i/002000/002537_hr1.png",
"shield": null
},
"7405": {
"cast": 0,
@ -239,7 +260,8 @@
"fr": "Troubadour",
"jp": "トルバドゥール"
},
"icon": "https://xivapi.com/i/002000/002612_hr1.png"
"icon": "https://xivapi.com/i/002000/002612_hr1.png",
"shield": null
},
"7432": {
"cast": 0,
@ -250,7 +272,8 @@
"fr": "Faveur divine",
"jp": "ディヴァインベニゾン"
},
"icon": "https://xivapi.com/i/002000/002638_hr1.png"
"icon": "https://xivapi.com/i/002000/002638_hr1.png",
"shield": "500 potency"
},
"7498": {
"cast": 0,
@ -261,7 +284,8 @@
"fr": "Troisième œil",
"jp": "心眼"
},
"icon": "https://xivapi.com/i/003000/003153_hr1.png"
"icon": "https://xivapi.com/i/003000/003153_hr1.png",
"shield": null
},
"7531": {
"cast": 0,
@ -272,7 +296,8 @@
"fr": "Rempart",
"jp": "ランパート"
},
"icon": "https://xivapi.com/i/000000/000801_hr1.png"
"icon": "https://xivapi.com/i/000000/000801_hr1.png",
"shield": null
},
"7535": {
"cast": 0,
@ -283,7 +308,8 @@
"fr": "Rétorsion",
"jp": "リプライザル"
},
"icon": "https://xivapi.com/i/000000/000806_hr1.png"
"icon": "https://xivapi.com/i/000000/000806_hr1.png",
"shield": null
},
"7549": {
"cast": 0,
@ -294,7 +320,8 @@
"fr": "Restreinte",
"jp": "牽制"
},
"icon": "https://xivapi.com/i/000000/000828_hr1.png"
"icon": "https://xivapi.com/i/000000/000828_hr1.png",
"shield": null
},
"7560": {
"cast": 0,
@ -305,7 +332,8 @@
"fr": "Embrouillement",
"jp": "アドル"
},
"icon": "https://xivapi.com/i/000000/000861_hr1.png"
"icon": "https://xivapi.com/i/000000/000861_hr1.png",
"shield": null
},
"16012": {
"cast": 0,
@ -316,7 +344,8 @@
"fr": "Samba protectrice",
"jp": "守りのサンバ"
},
"icon": "https://xivapi.com/i/003000/003469_hr1.png"
"icon": "https://xivapi.com/i/003000/003469_hr1.png",
"shield": null
},
"16140": {
"cast": 0,
@ -327,7 +356,8 @@
"fr": "Camouflage",
"jp": "カモフラージュ"
},
"icon": "https://xivapi.com/i/003000/003404_hr1.png"
"icon": "https://xivapi.com/i/003000/003404_hr1.png",
"shield": null
},
"16148": {
"cast": 0,
@ -338,7 +368,8 @@
"fr": "Nébuleuse",
"jp": "ネビュラ"
},
"icon": "https://xivapi.com/i/003000/003412_hr1.png"
"icon": "https://xivapi.com/i/003000/003412_hr1.png",
"shield": null
},
"16152": {
"cast": 0,
@ -349,7 +380,8 @@
"fr": "Bolide",
"jp": "ボーライド"
},
"icon": "https://xivapi.com/i/003000/003416_hr1.png"
"icon": "https://xivapi.com/i/003000/003416_hr1.png",
"shield": null
},
"16160": {
"cast": 0,
@ -360,7 +392,8 @@
"fr": "Cœur de Lumière",
"jp": "ハート・オブ・ライト"
},
"icon": "https://xivapi.com/i/003000/003424_hr1.png"
"icon": "https://xivapi.com/i/003000/003424_hr1.png",
"shield": null
},
"16161": {
"cast": 0,
@ -371,7 +404,8 @@
"fr": "Cœur de pierre",
"jp": "ハート・オブ・ストーン"
},
"icon": "https://xivapi.com/i/003000/003425_hr1.png"
"icon": "https://xivapi.com/i/003000/003425_hr1.png",
"shield": null
},
"16471": {
"cast": 0,
@ -382,7 +416,8 @@
"fr": "Missionnaire des Ténèbres",
"jp": "ダークミッショナリー"
},
"icon": "https://xivapi.com/i/003000/003087_hr1.png"
"icon": "https://xivapi.com/i/003000/003087_hr1.png",
"shield": null
},
"16536": {
"cast": 0,
@ -393,7 +428,8 @@
"fr": "Tempérance",
"jp": "テンパランス"
},
"icon": "https://xivapi.com/i/002000/002645_hr1.png"
"icon": "https://xivapi.com/i/002000/002645_hr1.png",
"shield": null
},
"16538": {
"cast": 0,
@ -404,7 +440,8 @@
"fr": "Illumination féérique",
"jp": "フェイイルミネーション"
},
"icon": "https://xivapi.com/i/002000/002853_hr1.png"
"icon": "https://xivapi.com/i/002000/002853_hr1.png",
"shield": null
},
"16548": {
"cast": 0,
@ -415,7 +452,8 @@
"fr": "Voile séraphique",
"jp": "セラフィックヴェール"
},
"icon": "https://xivapi.com/i/002000/002847_hr1.png"
"icon": "https://xivapi.com/i/002000/002847_hr1.png",
"shield": null
},
"16556": {
"cast": 0,
@ -426,7 +464,8 @@
"fr": "Rencontre céleste",
"jp": "星天交差"
},
"icon": "https://xivapi.com/i/003000/003556_hr1.png"
"icon": "https://xivapi.com/i/003000/003556_hr1.png",
"shield": "200% of HP restored"
},
"16559": {
"cast": 0,
@ -437,7 +476,8 @@
"fr": "Adepte de la neutralité",
"jp": "ニュートラルセクト"
},
"icon": "https://xivapi.com/i/003000/003552_hr1.png"
"icon": "https://xivapi.com/i/003000/003552_hr1.png",
"shield": "250% of HP restored"
},
"16889": {
"cast": 0,
@ -448,7 +488,8 @@
"fr": "Tacticien",
"jp": "タクティシャン"
},
"icon": "https://xivapi.com/i/003000/003040_hr1.png"
"icon": "https://xivapi.com/i/003000/003040_hr1.png",
"shield": null
},
"24291": {
"cast": 0,
@ -459,7 +500,8 @@
"fr": "Diagnosis eucrasique",
"jp": "エウクラシア・ディアグノシス"
},
"icon": "https://xivapi.com/i/003000/003659_hr1.png"
"icon": "https://xivapi.com/i/003000/003659_hr1.png",
"shield": null
},
"24292": {
"cast": 0,
@ -470,7 +512,8 @@
"fr": "Prognosis eucrasique",
"jp": "エウクラシア・プログノシス"
},
"icon": "https://xivapi.com/i/003000/003660_hr1.png"
"icon": "https://xivapi.com/i/003000/003660_hr1.png",
"shield": "320% of HP restored"
},
"24298": {
"cast": 0,
@ -481,7 +524,8 @@
"fr": "Kerachole",
"jp": "ケーラコレ"
},
"icon": "https://xivapi.com/i/003000/003666_hr1.png"
"icon": "https://xivapi.com/i/003000/003666_hr1.png",
"shield": null
},
"24305": {
"cast": 0,
@ -492,7 +536,8 @@
"fr": "Haima",
"jp": "ハイマ"
},
"icon": "https://xivapi.com/i/003000/003673_hr1.png"
"icon": "https://xivapi.com/i/003000/003673_hr1.png",
"shield": "300 potency"
},
"24310": {
"cast": 0,
@ -503,7 +548,8 @@
"fr": "Holos",
"jp": "ホーリズム"
},
"icon": "https://xivapi.com/i/003000/003678_hr1.png"
"icon": "https://xivapi.com/i/003000/003678_hr1.png",
"shield": null
},
"24311": {
"cast": 0,
@ -514,7 +560,8 @@
"fr": "Panhaima",
"jp": "パンハイマ"
},
"icon": "https://xivapi.com/i/003000/003679_hr1.png"
"icon": "https://xivapi.com/i/003000/003679_hr1.png",
"shield": "200 potency"
},
"24404": {
"cast": 0,
@ -525,7 +572,8 @@
"fr": "Blason arcanique",
"jp": "アルケインクレスト"
},
"icon": "https://xivapi.com/i/003000/003632_hr1.png"
"icon": "https://xivapi.com/i/003000/003632_hr1.png",
"shield": "10% max HP"
},
"25746": {
"cast": 0,
@ -536,7 +584,8 @@
"fr": "Schiltron sacré",
"jp": "ホーリーシェルトロン"
},
"icon": "https://xivapi.com/i/002000/002950_hr1.png"
"icon": "https://xivapi.com/i/002000/002950_hr1.png",
"shield": null
},
"25751": {
"cast": 0,
@ -547,7 +596,8 @@
"fr": "Intuition fougueuse",
"jp": "原初の血気"
},
"icon": "https://xivapi.com/i/002000/002569_hr1.png"
"icon": "https://xivapi.com/i/002000/002569_hr1.png",
"shield": "400 potency"
},
"25754": {
"cast": 0,
@ -558,7 +608,8 @@
"fr": "Oblation",
"jp": "オブレーション"
},
"icon": "https://xivapi.com/i/003000/003089_hr1.png"
"icon": "https://xivapi.com/i/003000/003089_hr1.png",
"shield": null
},
"25758": {
"cast": 0,
@ -569,7 +620,8 @@
"fr": "Cœur de corindon",
"jp": "ハート・オブ・コランダム"
},
"icon": "https://xivapi.com/i/003000/003430_hr1.png"
"icon": "https://xivapi.com/i/003000/003430_hr1.png",
"shield": null
},
"25789": {
"cast": 0,
@ -580,7 +632,8 @@
"fr": "Final improvisé",
"jp": "インプロビゼーション・フィニッシュ"
},
"icon": "https://xivapi.com/i/003000/003479_hr1.png"
"icon": "https://xivapi.com/i/003000/003479_hr1.png",
"shield": null
},
"25799": {
"cast": 0,
@ -591,7 +644,8 @@
"fr": "Égide rayonnante",
"jp": "守りの光"
},
"icon": "https://xivapi.com/i/002000/002750_hr1.png"
"icon": "https://xivapi.com/i/002000/002750_hr1.png",
"shield": "20% max HP"
},
"25857": {
"cast": 0,
@ -602,7 +656,8 @@
"fr": "Barrière anti-magie",
"jp": "バマジク"
},
"icon": "https://xivapi.com/i/003000/003237_hr1.png"
"icon": "https://xivapi.com/i/003000/003237_hr1.png",
"shield": null
},
"25868": {
"cast": 0,
@ -613,7 +668,8 @@
"fr": "Thèse fluidique",
"jp": "疾風怒濤の計"
},
"icon": "https://xivapi.com/i/002000/002878_hr1.png"
"icon": "https://xivapi.com/i/002000/002878_hr1.png",
"shield": null
},
"34685": {
"cast": 0,
@ -624,7 +680,8 @@
"fr": "Enduit a tempera",
"jp": "テンペラコート"
},
"icon": "https://xivapi.com/i/003000/003835_hr1.png"
"icon": "https://xivapi.com/i/003000/003835_hr1.png",
"shield": "20% max HP"
},
"34686": {
"cast": 0,
@ -635,7 +692,8 @@
"fr": "Tempera grassa",
"jp": "テンペラグラッサ"
},
"icon": "https://xivapi.com/i/003000/003836_hr1.png"
"icon": "https://xivapi.com/i/003000/003836_hr1.png",
"shield": "10% max HP"
},
"36920": {
"cast": 0,
@ -646,7 +704,8 @@
"fr": "Garde extrême",
"jp": "エクストリームガード"
},
"icon": "https://xivapi.com/i/002000/002524_hr1.png"
"icon": "https://xivapi.com/i/002000/002524_hr1.png",
"shield": null
},
"36923": {
"cast": 0,
@ -657,7 +716,8 @@
"fr": "Damnation",
"jp": "ダムネーション"
},
"icon": "https://xivapi.com/i/002000/002573_hr1.png"
"icon": "https://xivapi.com/i/002000/002573_hr1.png",
"shield": null
},
"36927": {
"cast": 0,
@ -668,7 +728,8 @@
"fr": "Vigile ténébreux",
"jp": "シャドウヴィジル"
},
"icon": "https://xivapi.com/i/003000/003094_hr1.png"
"icon": "https://xivapi.com/i/003000/003094_hr1.png",
"shield": null
},
"36935": {
"cast": 0,
@ -679,7 +740,8 @@
"fr": "Grande nébuleuse",
"jp": "グレートネビュラ"
},
"icon": "https://xivapi.com/i/003000/003435_hr1.png"
"icon": "https://xivapi.com/i/003000/003435_hr1.png",
"shield": null
},
"37011": {
"cast": 0,
@ -690,7 +752,8 @@
"fr": "Caresse divine",
"jp": "ディヴァインカレス"
},
"icon": "https://xivapi.com/i/002000/002128_hr1.png"
"icon": "https://xivapi.com/i/002000/002128_hr1.png",
"shield": "400 potency"
},
"37025": {
"cast": 0,
@ -701,7 +764,8 @@
"fr": "La Tour",
"jp": "ビエルゴの塔"
},
"icon": "https://xivapi.com/i/003000/003115_hr1.png"
"icon": "https://xivapi.com/i/003000/003115_hr1.png",
"shield": "400 potency"
},
"37034": {
"cast": 0,
@ -712,6 +776,7 @@
"fr": "Prognosis eucrasique II",
"jp": "エウクラシア・プログシスII"
},
"icon": "https://xivapi.com/i/003000/003689_hr1.png"
"icon": "https://xivapi.com/i/003000/003689_hr1.png",
"shield": "360% of HP restored"
}
}

View File

@ -150,6 +150,21 @@ function abilityIcon(ability) {
return MITIG_ICONS[ability] ?? actionMetaByName[ability]?.icon ?? '';
}
function abilityShieldText(ability) {
return actionMetaByName[ability]?.shield ?? '';
}
function abilityEffectTooltip(ability, buffType, plan = null) {
const lines = [localizedAbilityName(ability, plan)];
const dr = ABILITY_DR[ability] ?? 0;
const shield = abilityShieldText(ability);
if (dr > 0) lines.push(`Mitigation: ${Math.round(dr * 100)}%`);
if (shield) lines.push(`Shield: ${shield}`);
else if (buffType === 'shield') lines.push('Shield');
if (dr <= 0 && !shield && buffType !== 'shield') lines.push('No direct damage reduction');
return lines.join('\n');
}
async function ensureActionMetaLoaded() {
if (actionMetaPromise) return actionMetaPromise;
actionMetaPromise = (async () => {
@ -179,6 +194,7 @@ async function ensureActionMetaLoaded() {
jp: action.Name_ja ?? '',
},
icon: compact?.[id]?.icon ?? null,
shield: compact?.[id]?.shield ?? '',
cast: (parseInt(compact?.[id]?.cast ?? action.Cast100ms ?? 0, 10) || 0) / 10,
recast: (parseInt(compact?.[id]?.recast ?? action.Recast100ms ?? 0, 10) || 0) / 10,
duration: durations.find(Number.isFinite) ?? 15,
@ -193,10 +209,11 @@ async function ensureActionMetaLoaded() {
name: byId[id]?.name ?? names.en ?? '',
names: { ...(byId[id]?.names ?? {}), ...names },
icon: byId[id]?.icon ?? action.icon ?? '',
shield: byId[id]?.shield ?? action.shield ?? '',
cast: (parseInt(action.cast ?? 0, 10) || 0) / 10,
recast: (parseInt(action.recast ?? 0, 10) || 0) / 10,
};
if (names.en && !byName[names.en]) byName[names.en] = byId[id];
if (names.en) byName[names.en] = byId[id];
}
actionMetaById = byId;
actionMetaByName = byName;
@ -1115,12 +1132,13 @@ function renderTimelineHtml(plan) {
}
const icon = abilityIcon(row.ability);
const abilityDisplayName = localizedAbilityName(row.ability, plan);
const abilityTooltip = abilityEffectTooltip(row.ability, row.buffType, plan);
const jobStartCls = row.firstForJob ? ' timeline-player-row--job-start' : '';
return `
<div class="timeline-row timeline-player-row${jobStartCls}" data-row-idx="${row.idx}" data-job="${escHtml(row.job)}" data-ability="${escHtml(row.ability)}">
<div class="timeline-row-label">
<span class="timeline-job role-${escHtml(row.role)}">${escHtml(row.job)}</span>
<span class="timeline-row-ability">
<span class="timeline-row-ability" title="${escHtml(abilityTooltip)}">
${icon ? `<img src="${escHtml(icon)}" alt="" class="timeline-row-ability-icon">` : ''}
<span class="timeline-row-ability-name">${escHtml(abilityDisplayName)}</span>
</span>
@ -2462,11 +2480,12 @@ function renderAbilityModalContent() {
const icon = abilityIcon(ab.name);
const assignedName = assigned ? assignmentAbilityName(assigned, plan) : '';
const label = assignedName || localizedAbilityName(ab.name, plan);
const effectTitle = [title, abilityEffectTooltip(ab.name, ab.buffType, plan)].filter(Boolean).join('\n\n');
return `<button class="ability-chip ${cls}${activeClass}${otherClass}"
data-ability="${escHtml(ab.name)}"
data-job="${escHtml(job)}"
data-buff-type="${escHtml(ab.buffType)}"
${title ? `title="${title}"` : ''}
title="${escHtml(effectTitle)}"
>${icon ? `<img class="badge-icon" src="${escHtml(icon)}" alt="">` : ''}${escHtml(label)}</button>`;
}).join('');

View File

@ -324,6 +324,42 @@ function action_icon_url(array $action): ?string
return 'https://xivapi.com/i/' . $matches[1] . '/' . $matches[2] . '.png';
}
function plain_action_text(?string $text): string
{
if ($text === null || $text === '') {
return '';
}
$text = html_entity_decode(strip_tags($text), ENT_QUOTES | ENT_HTML5, 'UTF-8');
return trim((string)preg_replace('/\s+/u', ' ', $text));
}
function action_shield_text(array $action): ?string
{
$description = plain_action_text(action_text_field($action, 'Description_en'));
if ($description === '' || !preg_match('/barrier|absorbs|absorbed|nullif(?:y|ies)/i', $description)) {
return null;
}
if (preg_match('/(?:absorbs|absorb|nullifies|nullify)[^.]*?(?:totaling|up to)?\s*(\d+)%\s*(?:of\s*)?(?:your\s+|target\'s\s+)?maximum HP/i', $description, $m)) {
return $m[1] . '% max HP';
}
if (preg_match('/barrier[^.]*?(?:absorbs|absorb|nullifies|nullify)[^.]*?(\d+)%\s*(?:of\s*)?(?:your\s+|target\'s\s+)?maximum HP/i', $description, $m)) {
return $m[1] . '% max HP';
}
if (preg_match('/barrier[^.]*?(\d+)%\s+of\s+the\s+amount\s+of\s+HP\s+restored/i', $description, $m)) {
return $m[1] . '% of HP restored';
}
if (preg_match('/barrier[^.]*?(?:heal of|Cure Potency:)\s*(\d+)\s*potency/i', $description, $m)) {
return $m[1] . ' potency';
}
return null;
}
$plannerAbilityNames = read_planner_ability_names($plannerDataSource);
$actionIds = read_mitigation_action_ids($mitigationSource, $plannerAbilityNames);
$wanted = array_fill_keys(array_map('strval', $actionIds), true);
@ -353,6 +389,7 @@ foreach ($wanted as $id => $_) {
'jp' => action_text_field($action, 'Name_ja'),
],
'icon' => action_icon_url($action),
'shield' => action_shield_text($action),
];
}