Skip to content

Commit 33a09ab

Browse files
ishtartecclaude
andcommitted
fix: missing AP champions, localized spell names, ally spell display
- Add Mel, Aurora, Hwei, Zac, Malphite, and other missing AP champions to CHAMP_DAMAGE_TYPE so damage composition bar classifies them correctly - Fix Ignite (and other spells) not rendering for non-English LoL clients by matching on internal keys (SummonerDot, etc.) in addition to English names — rawDisplayName returns the internal key, not the translation - Show summoner spells for ally team during live game too, not just enemies (ally icons are static; enemy icons remain clickable for cooldown timers) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent b668bb0 commit 33a09ab

2 files changed

Lines changed: 38 additions & 15 deletions

File tree

src-tauri/src/lcu.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1788,18 +1788,21 @@ pub fn compute_gold_timeline(
17881788
}
17891789

17901790
fn spell_name_to_id(name: &str) -> i64 {
1791+
// Live Client Data returns `rawDisplayName` as the internal key like
1792+
// "GeneratedTip_SummonerSpell_SummonerDot_DisplayName" (Ignite). Match on
1793+
// both the internal key and the English display name to survive localization.
17911794
match name {
1792-
s if s.contains("Flash") => 4,
1793-
s if s.contains("Ignite") => 14,
1794-
s if s.contains("Teleport") => 12,
1795-
s if s.contains("Exhaust") => 3,
1796-
s if s.contains("Heal") => 7,
1797-
s if s.contains("Barrier") => 21,
1798-
s if s.contains("Cleanse") => 1,
1799-
s if s.contains("Ghost") => 6,
1800-
s if s.contains("Smite") => 11,
1801-
s if s.contains("Clarity") => 13,
1802-
s if s.contains("Mark") => 32, // ARAM snowball
1795+
s if s.contains("SummonerFlash") || s.contains("Flash") => 4,
1796+
s if s.contains("SummonerDot") || s.contains("Ignite") => 14,
1797+
s if s.contains("SummonerTeleport") || s.contains("Teleport") => 12,
1798+
s if s.contains("SummonerExhaust") || s.contains("Exhaust") => 3,
1799+
s if s.contains("SummonerHeal") || s.contains("Heal") => 7,
1800+
s if s.contains("SummonerBarrier") || s.contains("Barrier") => 21,
1801+
s if s.contains("SummonerBoost") || s.contains("Cleanse") => 1,
1802+
s if s.contains("SummonerHaste") || s.contains("Ghost") => 6,
1803+
s if s.contains("SummonerSmite") || s.contains("Smite") => 11,
1804+
s if s.contains("SummonerMana") || s.contains("Clarity") => 13,
1805+
s if s.contains("SummonerSnowball") || s.contains("Mark") => 32, // ARAM snowball
18031806
_ => 0,
18041807
}
18051808
}

src/App.tsx

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ const TRAIT_SHIELDERS = new Set([
420420
// Map champion ID to primary damage type: "ap" or "ad"
421421
const CHAMP_DAMAGE_TYPE: Record<number, "ap" | "ad"> = {};
422422
// AP champions
423-
[1,3,4,7,8,9,10,13,17,25,26,27,28,30,31,34,37,38,40,42,43,45,50,55,61,63,68,69,74,76,79,82,84,85,90,96,99,101,103,105,112,113,115,117,127,131,134,142,143,147,150,161,163,245,246,267,268,350,353,360,427,432,497,518,526,555,685,711,876,887,901,902,950].forEach(id => CHAMP_DAMAGE_TYPE[id] = "ap");
423+
[1,3,4,7,8,9,10,13,16,17,25,26,27,28,30,31,34,37,38,40,42,43,45,50,54,55,57,60,61,63,68,69,74,76,79,82,84,85,90,96,99,101,103,105,112,113,115,117,127,131,134,136,142,143,147,150,154,161,163,245,246,267,268,350,353,360,427,432,497,517,518,526,555,685,711,800,876,887,888,893,901,902,910,950].forEach(id => CHAMP_DAMAGE_TYPE[id] = "ap");
424424
// AD champions (rest default to AD for simplicity)
425425

426426
interface ItemRec {
@@ -2060,6 +2060,17 @@ function SpellCdIcon({ spellId, playerName, gameTime, spellTimers, onSpellClick
20602060
);
20612061
}
20622062

2063+
function SpellStaticIcon({ spellId }: { spellId: number }) {
2064+
const spellKey = SPELL_KEYS[spellId];
2065+
const spellName = SPELL_NAMES[spellId] || "Spell";
2066+
if (!spellKey) return <div className="spell-cd-wrap" title={spellName} />;
2067+
return (
2068+
<div className="spell-cd-wrap" title={spellName}>
2069+
<img src={spellIconUrl(spellId)} alt={spellName} className="spell-cd-img" />
2070+
</div>
2071+
);
2072+
}
2073+
20632074
function LiveGamePlayerCard({ p, onViewPlayer, isEnemy, spellCd }: { p: LiveGamePlayer; onViewPlayer?: (puuid: string) => void; isEnemy?: boolean; spellCd?: SpellCdProps }) {
20642075
const totalGames = p.ranked_wins + p.ranked_losses;
20652076
const champWr = p.champ_games > 0 ? (p.champ_wins / p.champ_games * 100) : 0;
@@ -2098,10 +2109,19 @@ function LiveGamePlayerCard({ p, onViewPlayer, isEnemy, spellCd }: { p: LiveGame
20982109
))}
20992110
</span>
21002111
</div>
2101-
{isEnemy && live && spellCd && (
2112+
{live && (live.spell1_id > 0 || live.spell2_id > 0) && (
21022113
<div className="lg-spells">
2103-
<SpellCdIcon spellId={live.spell1_id} playerName={p.summoner_name} {...spellCd} />
2104-
<SpellCdIcon spellId={live.spell2_id} playerName={p.summoner_name} {...spellCd} />
2114+
{isEnemy && spellCd ? (
2115+
<>
2116+
<SpellCdIcon spellId={live.spell1_id} playerName={p.summoner_name} {...spellCd} />
2117+
<SpellCdIcon spellId={live.spell2_id} playerName={p.summoner_name} {...spellCd} />
2118+
</>
2119+
) : (
2120+
<>
2121+
<SpellStaticIcon spellId={live.spell1_id} />
2122+
<SpellStaticIcon spellId={live.spell2_id} />
2123+
</>
2124+
)}
21052125
</div>
21062126
)}
21072127
{live ? (

0 commit comments

Comments
 (0)