Applique .gitattributes sur tous les fichiers existants. Élimine les différences fantômes entre WSL et Windows. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
258 lines
15 KiB
TypeScript
Executable File
258 lines
15 KiB
TypeScript
Executable File
// ══════════════════════════════════════════
|
|
// Race Value Object — extracted from index.html
|
|
// ══════════════════════════════════════════
|
|
|
|
export interface RaceData {
|
|
name: string;
|
|
stats: string[];
|
|
parents: string;
|
|
icon: string;
|
|
}
|
|
|
|
// Generation → color
|
|
export const GEN_COLORS: Record<number, string> = {
|
|
1: '#c8622a',
|
|
2: '#e8b820',
|
|
3: '#6040b0',
|
|
4: '#2a8acc',
|
|
5: '#c03050',
|
|
6: '#d040a0',
|
|
7: '#c8c0a0',
|
|
8: '#20a8b0',
|
|
9: '#28a058',
|
|
10: '#8050a0',
|
|
};
|
|
|
|
// Base race → primary color
|
|
export const RACE_BASE_COLORS: Record<string, string> = {
|
|
'Rousse': '#c8622a',
|
|
'Amande': '#d4b48a',
|
|
'Dorée': '#e8b820',
|
|
'Ebène': '#2a2a2a',
|
|
'Indigo': '#6040b0',
|
|
'Pourpre': '#c03050',
|
|
'Orchidée': '#d040a0',
|
|
'Ivoire': '#c8c0a0',
|
|
'Turquoise': '#20a8b0',
|
|
'Emeraude': '#28a058',
|
|
'Prune': '#8050a0',
|
|
};
|
|
|
|
// All race definitions by generation
|
|
export const RACES_DATA: Record<number, RaceData[]> = {
|
|
2: [
|
|
{ name: 'Amande et Rousse', stats: ['400 Vitalité', '60 Soins', '1200 Initiative'], parents: 'Amande + Rousse', icon: '🐦' },
|
|
{ name: 'Dorée et Rousse', stats: ['400 Vitalité', '1 Invocation', '45 Soins'], parents: 'Dorée + Rousse', icon: '🐦' },
|
|
{ name: 'Amande et Dorée', stats: ['400 Vitalité', '1 Invocation', '1200 Initiative'], parents: 'Amande + Dorée', icon: '🐦' },
|
|
],
|
|
3: [
|
|
{ name: 'Ebène', stats: ['400 Vitalité', '120 Agilité'], parents: 'Amande et Dorée + Dorée et Rousse', icon: '🐦' },
|
|
{ name: 'Indigo', stats: ['400 Vitalité', '120 Chance'], parents: 'Amande et Dorée + Amande et Rousse', icon: '🐦' },
|
|
],
|
|
4: [
|
|
{ name: 'Indigo et Rousse', stats: ['400 Vitalité', '90 Chance', '45 Soins'], parents: 'Indigo + Rousse', icon: '🐦' },
|
|
{ name: 'Ebène et Rousse', stats: ['400 Vitalité', '90 Agilité', '45 Soins'], parents: 'Ebène + Rousse', icon: '🐦' },
|
|
{ name: 'Amande et Indigo', stats: ['400 Vitalité', '90 Chance', '1200 Initiative'], parents: 'Amande + Indigo', icon: '🐦' },
|
|
{ name: 'Amande et Ebène', stats: ['400 Vitalité', '120 Agilité', '1200 Initiative'], parents: 'Amande + Ebène', icon: '🐦' },
|
|
{ name: 'Dorée et Indigo', stats: ['400 Vitalité', '90 Chance', '1 Invocation'], parents: 'Dorée + Indigo', icon: '🐦' },
|
|
{ name: 'Dorée et Ebène', stats: ['400 Vitalité', '90 Agilité', '1 Invocation'], parents: 'Dorée + Ebène', icon: '🐦' },
|
|
{ name: 'Ebène et Indigo', stats: ['400 Vitalité', '90 Chance', '90 Agilité'], parents: 'Ebène + Indigo', icon: '🐦' },
|
|
],
|
|
5: [
|
|
{ name: 'Pourpre', stats: ['400 Vitalité', '120 Force'], parents: 'Ebène et Indigo + Amande et Rousse', icon: '🐦' },
|
|
{ name: 'Orchidée', stats: ['400 Vitalité', '120 Intelligence'], parents: 'Ebène et Indigo + Dorée et Rousse', icon: '🐦' },
|
|
],
|
|
6: [
|
|
{ name: 'Pourpre et Rousse', stats: ['400 Vitalité', '90 Force', '45 Soins'], parents: 'Pourpre + Rousse', icon: '🐦' },
|
|
{ name: 'Orchidée et Rousse', stats: ['400 Vitalité', '90 Intelligence', '45 Soins'], parents: 'Orchidée + Rousse', icon: '🐦' },
|
|
{ name: 'Amande et Pourpre', stats: ['400 Vitalité', '90 Force', '1200 Initiative'], parents: 'Amande + Pourpre', icon: '🐦' },
|
|
{ name: 'Amande et Orchidée', stats: ['400 Vitalité', '90 Intelligence', '1200 Initiative'], parents: 'Amande + Orchidée', icon: '🐦' },
|
|
{ name: 'Dorée et Pourpre', stats: ['400 Vitalité', '90 Force', '1 Invocation'], parents: 'Dorée + Pourpre', icon: '🐦' },
|
|
{ name: 'Dorée et Orchidée', stats: ['400 Vitalité', '90 Intelligence', '1 Invocation'], parents: 'Dorée + Orchidée', icon: '🐦' },
|
|
{ name: 'Indigo et Pourpre', stats: ['400 Vitalité', '90 Force', '90 Chance'], parents: 'Indigo + Pourpre', icon: '🐦' },
|
|
{ name: 'Indigo et Orchidée', stats: ['400 Vitalité', '90 Intelligence', '90 Chance'], parents: 'Indigo + Orchidée', icon: '🐦' },
|
|
{ name: 'Ebène et Pourpre', stats: ['400 Vitalité', '90 Force', '90 Agilité'], parents: 'Ebène + Pourpre', icon: '🐦' },
|
|
{ name: 'Ebène et Orchidée', stats: ['400 Vitalité', '90 Intelligence', '90 Agilité'], parents: 'Ebène + Orchidée', icon: '🐦' },
|
|
{ name: 'Orchidée et Pourpre', stats: ['400 Vitalité', '90 Force', '90 Intelligence'], parents: 'Orchidée + Pourpre', icon: '🐦' },
|
|
],
|
|
7: [
|
|
{ name: 'Ivoire', stats: ['400 Vitalité', '90 Puissance'], parents: 'Orchidée et Pourpre + Indigo et Pourpre', icon: '🐦' },
|
|
{ name: 'Turquoise', stats: ['400 Vitalité', '90 Prospection'], parents: 'Orchidée et Pourpre + Ebène et Orchidée', icon: '🐦' },
|
|
],
|
|
8: [
|
|
{ name: 'Ivoire et Rousse', stats: ['400 Vitalité', '70 Puissance', '45 Soins'], parents: 'Ivoire + Rousse', icon: '🐦' },
|
|
{ name: 'Turquoise et Rousse', stats: ['400 Vitalité', '45 Soins', '70 Prospection'], parents: 'Turquoise + Rousse', icon: '🐦' },
|
|
{ name: 'Amande et Ivoire', stats: ['400 Vitalité', '70 Puissance', '1200 Initiative'], parents: 'Amande + Ivoire', icon: '🐦' },
|
|
{ name: 'Amande et Turquoise', stats: ['400 Vitalité', '70 Prospection', '1200 Initiative'], parents: 'Amande + Turquoise', icon: '🐦' },
|
|
{ name: 'Dorée et Ivoire', stats: ['400 Vitalité', '70 Puissance', '1 Invocation'], parents: 'Dorée + Ivoire', icon: '🐦' },
|
|
{ name: 'Dorée et Turquoise', stats: ['400 Vitalité', '1 Invocation', '70 Prospection'], parents: 'Dorée + Turquoise', icon: '🐦' },
|
|
{ name: 'Indigo et Ivoire', stats: ['400 Vitalité', '90 Chance', '70 Puissance'], parents: 'Indigo + Ivoire', icon: '🐦' },
|
|
{ name: 'Indigo et Turquoise', stats: ['400 Vitalité', '90 Chance', '70 Prospection'], parents: 'Indigo + Turquoise', icon: '🐦' },
|
|
{ name: 'Ebène et Ivoire', stats: ['400 Vitalité', '90 Agilité', '70 Puissance'], parents: 'Ebène + Ivoire', icon: '🐦' },
|
|
{ name: 'Ebène et Turquoise', stats: ['400 Vitalité', '90 Agilité', '70 Prospection'], parents: 'Ebène + Turquoise', icon: '🐦' },
|
|
{ name: 'Ivoire et Pourpre', stats: ['400 Vitalité', '90 Force', '70 Puissance'], parents: 'Ivoire + Pourpre', icon: '🐦' },
|
|
{ name: 'Turquoise et Pourpre', stats: ['400 Vitalité', '90 Force', '70 Prospection'], parents: 'Turquoise + Pourpre', icon: '🐦' },
|
|
{ name: 'Ivoire et Orchidée', stats: ['400 Vitalité', '90 Intelligence', '70 Puissance'], parents: 'Ivoire + Orchidée', icon: '🐦' },
|
|
{ name: 'Turquoise et Orchidée', stats: ['400 Vitalité', '90 Intelligence', '70 Prospection'], parents: 'Turquoise + Orchidée', icon: '🐦' },
|
|
{ name: 'Ivoire et Turquoise', stats: ['400 Vitalité', '70 Puissance', '70 Prospection'], parents: 'Ivoire + Turquoise', icon: '🐦' },
|
|
],
|
|
9: [
|
|
{ name: 'Emeraude', stats: ['400 Vitalité', '14% Critique'], parents: 'Ivoire et Turquoise + Ivoire et Pourpre', icon: '🐦' },
|
|
{ name: 'Prune', stats: ['400 Vitalité', '2 Portée'], parents: 'Ivoire et Turquoise + Turquoise et Orchidée', icon: '🐦' },
|
|
],
|
|
10: [
|
|
{ name: 'Emeraude et Rousse', stats: ['400 Vitalité', '10% Critique', '45 Soins'], parents: 'Emeraude + Rousse', icon: '🐦' },
|
|
{ name: 'Prune et Rousse', stats: ['400 Vitalité', '1 Portée', '45 Soins'], parents: 'Prune + Rousse', icon: '🐦' },
|
|
{ name: 'Amande et Emeraude', stats: ['400 Vitalité', '10% Critique', '1200 Initiative'], parents: 'Amande + Emeraude', icon: '🐦' },
|
|
{ name: 'Prune et Amande', stats: ['400 Vitalité', '1 Portée', '1200 Initiative'], parents: 'Prune + Amande', icon: '🐦' },
|
|
{ name: 'Dorée et Emeraude', stats: ['400 Vitalité', '10% Critique', '1 Invocation'], parents: 'Dorée + Emeraude', icon: '🐦' },
|
|
{ name: 'Prune et Dorée', stats: ['400 Vitalité', '1 Portée', '1 Invocation'], parents: 'Prune + Dorée', icon: '🐦' },
|
|
{ name: 'Emeraude et Indigo', stats: ['400 Vitalité', '90 Chance', '10% Critique'], parents: 'Emeraude + Indigo', icon: '🐦' },
|
|
{ name: 'Prune et Indigo', stats: ['400 Vitalité', '90 Chance', '1 Portée'], parents: 'Prune + Indigo', icon: '🐦' },
|
|
{ name: 'Ebène et Emeraude', stats: ['400 Vitalité', '90 Agilité', '10% Critique'], parents: 'Ebène + Emeraude', icon: '🐦' },
|
|
{ name: 'Prune et Ebène', stats: ['400 Vitalité', '90 Agilité', '1 Portée'], parents: 'Prune + Ebène', icon: '🐦' },
|
|
{ name: 'Emeraude et Pourpre', stats: ['400 Vitalité', '90 Force', '10% Critique'], parents: 'Emeraude + Pourpre', icon: '🐦' },
|
|
{ name: 'Prune et Pourpre', stats: ['400 Vitalité', '90 Force', '1 Portée'], parents: 'Prune + Pourpre', icon: '🐦' },
|
|
{ name: 'Emeraude et Orchidée', stats: ['400 Vitalité', '90 Intelligence', '10% Critique'], parents: 'Emeraude + Orchidée', icon: '🐦' },
|
|
{ name: 'Prune et Orchidée', stats: ['400 Vitalité', '90 Intelligence', '1 Portée'], parents: 'Prune + Orchidée', icon: '🐦' },
|
|
{ name: 'Emeraude et Ivoire', stats: ['400 Vitalité', '70 Puissance', '10% Critique'], parents: 'Emeraude + Ivoire', icon: '🐦' },
|
|
{ name: 'Prune et Ivoire', stats: ['400 Vitalité', '70 Puissance', '1 Portée'], parents: 'Prune + Ivoire', icon: '🐦' },
|
|
{ name: 'Emeraude et Turquoise', stats: ['400 Vitalité', '10% Critique', '70 Prospection'], parents: 'Emeraude + Turquoise', icon: '🐦' },
|
|
{ name: 'Prune et Turquoise', stats: ['400 Vitalité', '1 Portée', '70 Prospection'], parents: 'Prune + Turquoise', icon: '🐦' },
|
|
{ name: 'Prune et Emeraude', stats: ['400 Vitalité', '10% Critique', '1 Portée'], parents: 'Prune + Emeraude', icon: '🐦' },
|
|
],
|
|
};
|
|
|
|
// Breeding recipes: baby race → [parentA, parentB]
|
|
export const BREEDING_RECIPES: Record<string, [string, string]> = {
|
|
'Dorée et Rousse': ['Rousse', 'Dorée'],
|
|
'Amande et Dorée': ['Amande', 'Dorée'],
|
|
'Amande et Rousse': ['Amande', 'Rousse'],
|
|
'Ebène': ['Amande et Dorée', 'Dorée et Rousse'],
|
|
'Indigo': ['Amande et Dorée', 'Amande et Rousse'],
|
|
'Indigo et Rousse': ['Indigo', 'Rousse'],
|
|
'Ebène et Rousse': ['Ebène', 'Rousse'],
|
|
'Amande et Indigo': ['Amande', 'Indigo'],
|
|
'Amande et Ebène': ['Amande', 'Ebène'],
|
|
'Dorée et Indigo': ['Dorée', 'Indigo'],
|
|
'Dorée et Ebène': ['Dorée', 'Ebène'],
|
|
'Ebène et Indigo': ['Ebène', 'Indigo'],
|
|
'Pourpre': ['Ebène et Indigo', 'Amande et Rousse'],
|
|
'Orchidée': ['Ebène et Indigo', 'Dorée et Rousse'],
|
|
'Pourpre et Rousse': ['Pourpre', 'Rousse'],
|
|
'Orchidée et Rousse': ['Orchidée', 'Rousse'],
|
|
'Amande et Pourpre': ['Amande', 'Pourpre'],
|
|
'Amande et Orchidée': ['Amande', 'Orchidée'],
|
|
'Dorée et Pourpre': ['Dorée', 'Pourpre'],
|
|
'Dorée et Orchidée': ['Dorée', 'Orchidée'],
|
|
'Indigo et Pourpre': ['Indigo', 'Pourpre'],
|
|
'Indigo et Orchidée': ['Indigo', 'Orchidée'],
|
|
'Ebène et Pourpre': ['Ebène', 'Pourpre'],
|
|
'Ebène et Orchidée': ['Ebène', 'Orchidée'],
|
|
'Orchidée et Pourpre': ['Orchidée', 'Pourpre'],
|
|
'Ivoire': ['Orchidée et Pourpre', 'Indigo et Pourpre'],
|
|
'Turquoise': ['Orchidée et Pourpre', 'Ebène et Orchidée'],
|
|
'Ivoire et Rousse': ['Ivoire', 'Rousse'],
|
|
'Turquoise et Rousse': ['Turquoise', 'Rousse'],
|
|
'Amande et Ivoire': ['Amande', 'Ivoire'],
|
|
'Amande et Turquoise': ['Amande', 'Turquoise'],
|
|
'Dorée et Ivoire': ['Dorée', 'Ivoire'],
|
|
'Dorée et Turquoise': ['Dorée', 'Turquoise'],
|
|
'Indigo et Ivoire': ['Indigo', 'Ivoire'],
|
|
'Indigo et Turquoise': ['Indigo', 'Turquoise'],
|
|
'Ebène et Ivoire': ['Ebène', 'Ivoire'],
|
|
'Ebène et Turquoise': ['Ebène', 'Turquoise'],
|
|
'Ivoire et Pourpre': ['Ivoire', 'Pourpre'],
|
|
'Turquoise et Pourpre': ['Turquoise', 'Pourpre'],
|
|
'Ivoire et Orchidée': ['Ivoire', 'Orchidée'],
|
|
'Turquoise et Orchidée': ['Turquoise', 'Orchidée'],
|
|
'Ivoire et Turquoise': ['Ivoire', 'Turquoise'],
|
|
'Emeraude': ['Ivoire et Turquoise', 'Ivoire et Pourpre'],
|
|
'Prune': ['Ivoire et Turquoise', 'Turquoise et Orchidée'],
|
|
'Emeraude et Rousse': ['Emeraude', 'Rousse'],
|
|
'Prune et Rousse': ['Prune', 'Rousse'],
|
|
'Amande et Emeraude': ['Amande', 'Emeraude'],
|
|
'Prune et Amande': ['Prune', 'Amande'],
|
|
'Dorée et Emeraude': ['Dorée', 'Emeraude'],
|
|
'Prune et Dorée': ['Prune', 'Dorée'],
|
|
'Emeraude et Indigo': ['Emeraude', 'Indigo'],
|
|
'Prune et Indigo': ['Prune', 'Indigo'],
|
|
'Ebène et Emeraude': ['Ebène', 'Emeraude'],
|
|
'Prune et Ebène': ['Prune', 'Ebène'],
|
|
'Emeraude et Pourpre': ['Emeraude', 'Pourpre'],
|
|
'Prune et Pourpre': ['Prune', 'Pourpre'],
|
|
'Emeraude et Orchidée': ['Emeraude', 'Orchidée'],
|
|
'Prune et Orchidée': ['Prune', 'Orchidée'],
|
|
'Emeraude et Ivoire': ['Emeraude', 'Ivoire'],
|
|
'Prune et Ivoire': ['Prune', 'Ivoire'],
|
|
'Emeraude et Turquoise': ['Emeraude', 'Turquoise'],
|
|
'Prune et Turquoise': ['Prune', 'Turquoise'],
|
|
'Prune et Emeraude': ['Prune', 'Emeraude'],
|
|
};
|
|
|
|
// Race name → generation number (computed)
|
|
export const RACE_GEN: Record<string, number> = {};
|
|
['Rousse', 'Dorée', 'Amande'].forEach((n) => (RACE_GEN[n] = 1));
|
|
Object.entries(RACES_DATA).forEach(([g, rs]) =>
|
|
rs.forEach((r) => (RACE_GEN[r.name] = parseInt(g))),
|
|
);
|
|
|
|
// Reverse lookup: "ParentA|ParentB" → baby race
|
|
export const BREEDING_BY_PARENTS: Record<string, string> = {};
|
|
Object.entries(BREEDING_RECIPES).forEach(([baby, [a, b]]) => {
|
|
BREEDING_BY_PARENTS[a + '|' + b] = baby;
|
|
if (a !== b) BREEDING_BY_PARENTS[b + '|' + a] = baby;
|
|
});
|
|
|
|
// For a given parent, which partners are possible?
|
|
export const COMPATIBLE_PARTNERS: Record<
|
|
string,
|
|
{ partner: string; baby: string; gen: number }[]
|
|
> = {};
|
|
Object.entries(BREEDING_RECIPES).forEach(([baby, [a, b]]) => {
|
|
if (!COMPATIBLE_PARTNERS[a]) COMPATIBLE_PARTNERS[a] = [];
|
|
COMPATIBLE_PARTNERS[a].push({ partner: b, baby, gen: RACE_GEN[baby] });
|
|
if (a !== b) {
|
|
if (!COMPATIBLE_PARTNERS[b]) COMPATIBLE_PARTNERS[b] = [];
|
|
COMPATIBLE_PARTNERS[b].push({ partner: a, baby, gen: RACE_GEN[baby] });
|
|
}
|
|
});
|
|
|
|
// ── Helper functions ──
|
|
|
|
const COLOR_ORDER = [
|
|
'Emeraude', 'Prune', 'Ivoire', 'Turquoise',
|
|
'Orchidée', 'Pourpre', 'Indigo', 'Ebène',
|
|
'Dorée', 'Amande', 'Rousse',
|
|
];
|
|
|
|
/** Returns the generation number for a race name. */
|
|
export function generationOf(name: string): number {
|
|
return RACE_GEN[name] ?? 0;
|
|
}
|
|
|
|
/** Returns true if the race is a base (gen 1) race. */
|
|
export function isBaseRace(name: string): boolean {
|
|
return RACE_GEN[name] === 1;
|
|
}
|
|
|
|
/** Returns the primary color for a race name. */
|
|
export function raceColor(name: string): string {
|
|
for (const k of COLOR_ORDER) {
|
|
if (name.includes(k)) return RACE_BASE_COLORS[k];
|
|
}
|
|
return '#888';
|
|
}
|
|
|
|
/** Returns the secondary color for gradient, or null if none. */
|
|
export function raceColor2(name: string): string | null {
|
|
let found = false;
|
|
for (const k of COLOR_ORDER) {
|
|
if (name.includes(k)) {
|
|
if (found) return RACE_BASE_COLORS[k];
|
|
found = true;
|
|
}
|
|
}
|
|
return null;
|
|
}
|