Armería: PvP campos de batalla, logros por categoría, bandas/mazmorras y página de hermandad
- PvP: pestaña Campos de batalla (pvpstats) con resultado, stats por partida y fecha/hora. - Logros: rejilla por categoría con anillos de progreso + detalle por categoría (datos de Achievement.db2 + Achievement_Category.db2, iconos vía wowhead). - Bandas: progreso por dificultad (10/25/heroico) con jefes reales de DungeonEncounter.db2 y tooltip de jefes; agrupado por expansión (Clásico/TBC/WotLK). - Mazmorras: mismo sistema, Normal + Heroico, Clásico/TBC/WotLK. - Página de hermandad estilo armería: cabecera (emblema, puntos = unión de logros de miembros sin duplicar, nº miembros, fundada), pestañas Hermandad/Logros, roster con iconos de clase/raza, columna Función (rol por spec), filtros clase/función, orden por rango/puntos/nivel de objeto/nivel/nombre, paginación. - Barra lateral: mensaje diario con login (iron-session, gated por pertenencia), logros recientes y desgloses de clases y funciones. - Cabecera de personaje: enlace a la hermandad + nombre del reino. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,39 +1,43 @@
|
||||
import { wowheadUrl, wowheadData, wowheadIcon } from '@/lib/wowhead'
|
||||
import { wowheadIcon, wowheadUrl, wowheadData } from '@/lib/wowhead'
|
||||
|
||||
export type TalentCell = { tier: number; col: number; rank: number; max: number; spell: number }
|
||||
export type TalentTreeData = { index: number; name: string; points: number; talents: TalentCell[] }
|
||||
|
||||
/**
|
||||
* Árbol de talentos estilo calculador: 3 árboles, cada uno una rejilla de casillas
|
||||
* posicionadas por fila (tier) y columna. Cada casilla muestra el icono del talento
|
||||
* (del hechizo de rango 1) y su rango actual/máximo; las no aprendidas van atenuadas.
|
||||
* El icono va en un <span> hijo porque wowhead sobrescribe el background del <a>.
|
||||
*/
|
||||
export function ArmoryTalents({
|
||||
trees,
|
||||
spec,
|
||||
total,
|
||||
maxPoints,
|
||||
locale,
|
||||
spellIcons,
|
||||
}: {
|
||||
trees: TalentTreeData[]
|
||||
export type GlyphInfo = { name: string; icon: string }
|
||||
export type TalentGroupView = {
|
||||
spec: string | null
|
||||
total: number
|
||||
maxPoints: number
|
||||
locale: string
|
||||
dist: number[]
|
||||
trees: TalentTreeData[]
|
||||
glyphs: { major: GlyphInfo[]; minor: GlyphInfo[] }
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderiza UN grupo de talentos: cabecera de distribución + los 3 árboles (rejilla de
|
||||
* iconos) + una 4ª columna con los Glifos (mayores/menores). Componente puro sin estado,
|
||||
* usado por ArmoryTalentTab (que conmuta Primaria/Secundaria).
|
||||
*/
|
||||
export function ArmoryTalents({
|
||||
group,
|
||||
spellIcons,
|
||||
locale,
|
||||
labels,
|
||||
}: {
|
||||
group: TalentGroupView
|
||||
spellIcons: Record<number, string>
|
||||
locale: string
|
||||
labels: { distribution: string; groupLabel: string; glyphs: string; majorGlyphs: string; minorGlyphs: string }
|
||||
}) {
|
||||
const { trees, glyphs, dist } = group
|
||||
return (
|
||||
<div className="armory-talents">
|
||||
<div className="armory-spec">
|
||||
<span className="armory-spec-name">{spec}</span>
|
||||
<span className="armory-spec-dist">{trees.map((tr) => tr.points).join(' / ')}</span>
|
||||
<span className="armory-spec-total">
|
||||
{total} / {maxPoints}
|
||||
</span>
|
||||
<div className="armory-tdist">
|
||||
<div className="armory-tdist-label">
|
||||
{labels.distribution} · {labels.groupLabel.toUpperCase()}
|
||||
</div>
|
||||
<div className="armory-tdist-value">{dist.join(' / ')}</div>
|
||||
</div>
|
||||
<div className="armory-talent-trees">
|
||||
|
||||
<div className="armory-talent-cols">
|
||||
{trees.map((tree) => {
|
||||
const maxTier = tree.talents.reduce((m, t) => Math.max(m, t.tier), 0)
|
||||
return (
|
||||
@@ -76,6 +80,42 @@ export function ArmoryTalents({
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
|
||||
<div className="armory-talent-tree armory-glyph-col">
|
||||
<div className="armory-talent-tree-head">
|
||||
<span>{labels.glyphs}</span>
|
||||
<span className="armory-talent-tree-pts">
|
||||
{glyphs.major.length} · {glyphs.minor.length}
|
||||
</span>
|
||||
</div>
|
||||
{glyphs.major.length > 0 && (
|
||||
<div className="armory-glyph-group">
|
||||
<h3 className="armory-prof-grouptitle">{labels.majorGlyphs}</h3>
|
||||
{glyphs.major.map((g, i) => (
|
||||
<div className="armory-glyph" key={i}>
|
||||
<span className="armory-glyph-icon" style={{ backgroundImage: `url(${wowheadIcon(g.icon, 'small')})` }} />
|
||||
<span className="armory-glyph-name">{g.name}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{glyphs.minor.length > 0 && (
|
||||
<div className="armory-glyph-group">
|
||||
<h3 className="armory-prof-grouptitle">{labels.minorGlyphs}</h3>
|
||||
{glyphs.minor.map((g, i) => (
|
||||
<div className="armory-glyph" key={i}>
|
||||
<span className="armory-glyph-icon" style={{ backgroundImage: `url(${wowheadIcon(g.icon, 'small')})` }} />
|
||||
<span className="armory-glyph-name">{g.name}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{glyphs.major.length === 0 && glyphs.minor.length === 0 && (
|
||||
<p className="armory-hint" style={{ padding: '8px 0' }}>
|
||||
—
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user