85 lines
4.6 KiB
TypeScript
85 lines
4.6 KiB
TypeScript
export type TypeName =
|
|
| 'Normal' | 'Fire' | 'Water' | 'Electric' | 'Grass' | 'Ice'
|
|
| 'Fighting' | 'Poison' | 'Ground' | 'Flying' | 'Psychic' | 'Bug'
|
|
| 'Rock' | 'Ghost' | 'Dragon' | 'Dark' | 'Steel' | 'Fairy';
|
|
|
|
export interface TypeInfo {
|
|
name: TypeName;
|
|
backgroundColor: string;
|
|
color: string;
|
|
}
|
|
|
|
export const TYPES: TypeInfo[] = [
|
|
{ name: 'Normal', backgroundColor: '#a4acaf', color: '#212124' },
|
|
{ name: 'Fire', backgroundColor: '#fd7d24', color: '#ffffff' },
|
|
{ name: 'Water', backgroundColor: '#4792C4', color: '#ffffff' },
|
|
{ name: 'Electric', backgroundColor: '#eed535', color: '#212121' },
|
|
{ name: 'Grass', backgroundColor: '#9bcc50', color: '#212121' },
|
|
{ name: 'Ice', backgroundColor: '#90d5d5', color: '#212121' },
|
|
{ name: 'Fighting', backgroundColor: '#d56723', color: '#ffffff' },
|
|
{ name: 'Poison', backgroundColor: '#b97fc9', color: '#ffffff' },
|
|
{ name: 'Ground', backgroundColor: '#debb5c', color: '#212121' },
|
|
{ name: 'Flying', backgroundColor: '#3dc7ef', color: '#212121' },
|
|
{ name: 'Psychic', backgroundColor: '#f366b9', color: '#ffffff' },
|
|
{ name: 'Bug', backgroundColor: '#7e9f56', color: '#ffffff' },
|
|
{ name: 'Rock', backgroundColor: '#a38c21', color: '#ffffff' },
|
|
{ name: 'Ghost', backgroundColor: '#7b62a3', color: '#ffffff' },
|
|
{ name: 'Dragon', backgroundColor: '#53a4cf', color: '#ffffff' },
|
|
{ name: 'Dark', backgroundColor: '#707070', color: '#ffffff' },
|
|
{ name: 'Steel', backgroundColor: '#9eb7b8', color: '#212121' },
|
|
{ name: 'Fairy', backgroundColor: '#fdb9e9', color: '#212121' },
|
|
];
|
|
|
|
const TYPE_NAMES = TYPES.map(t => t.name);
|
|
|
|
const EFFECTIVENESS_FLAT: number[] = [
|
|
// NOR FIR WAT ELE GRA ICE FIG POI GRO FLY PSY BUG ROC GHO DRA DAR STE FAI
|
|
1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 0.50, 0.00, 1.00, 1.00, 0.50, 1.00, // NOR
|
|
1.00, 0.50, 0.50, 1.00, 2.00, 2.00, 1.00, 1.00, 1.00, 1.00, 1.00, 2.00, 0.50, 1.00, 0.50, 1.00, 2.00, 1.00, // FIR
|
|
1.00, 2.00, 0.50, 1.00, 0.50, 1.00, 1.00, 1.00, 2.00, 1.00, 1.00, 1.00, 2.00, 1.00, 0.50, 1.00, 1.00, 1.00, // WAT
|
|
1.00, 1.00, 2.00, 0.50, 0.50, 1.00, 1.00, 1.00, 0.00, 2.00, 1.00, 1.00, 1.00, 1.00, 0.50, 1.00, 1.00, 1.00, // ELE
|
|
1.00, 0.50, 2.00, 1.00, 0.50, 1.00, 1.00, 0.50, 2.00, 0.50, 1.00, 0.50, 2.00, 1.00, 0.50, 1.00, 0.50, 1.00, // GRA
|
|
1.00, 0.50, 0.50, 1.00, 2.00, 0.50, 1.00, 1.00, 2.00, 2.00, 1.00, 1.00, 1.00, 1.00, 2.00, 1.00, 0.50, 1.00, // ICE
|
|
2.00, 1.00, 1.00, 1.00, 1.00, 2.00, 1.00, 0.50, 1.00, 0.50, 0.50, 0.50, 2.00, 0.00, 1.00, 2.00, 2.00, 0.50, // FIG
|
|
1.00, 1.00, 1.00, 1.00, 2.00, 1.00, 1.00, 0.50, 0.50, 1.00, 1.00, 1.00, 0.50, 0.50, 1.00, 1.00, 0.00, 2.00, // POI
|
|
1.00, 2.00, 1.00, 2.00, 0.50, 1.00, 1.00, 2.00, 1.00, 0.00, 1.00, 0.50, 2.00, 1.00, 1.00, 1.00, 2.00, 1.00, // GRO
|
|
1.00, 1.00, 1.00, 0.50, 2.00, 1.00, 2.00, 1.00, 1.00, 1.00, 1.00, 2.00, 0.50, 1.00, 1.00, 1.00, 0.50, 1.00, // FLY
|
|
1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 2.00, 2.00, 1.00, 1.00, 0.50, 1.00, 1.00, 1.00, 1.00, 0.00, 0.50, 1.00, // PSY
|
|
1.00, 0.50, 1.00, 1.00, 2.00, 1.00, 0.50, 0.50, 1.00, 0.50, 2.00, 1.00, 1.00, 0.50, 1.00, 2.00, 0.50, 0.50, // BUG
|
|
1.00, 2.00, 1.00, 1.00, 1.00, 2.00, 0.50, 1.00, 0.50, 2.00, 1.00, 2.00, 1.00, 1.00, 1.00, 1.00, 0.50, 1.00, // ROC
|
|
0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 2.00, 1.00, 1.00, 2.00, 1.00, 0.50, 1.00, 1.00, // GHO
|
|
1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 2.00, 1.00, 0.50, 0.00, // DRA
|
|
1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 0.50, 1.00, 1.00, 1.00, 2.00, 1.00, 1.00, 2.00, 1.00, 0.50, 1.00, 0.50, // DAR
|
|
1.00, 0.50, 0.50, 0.50, 1.00, 2.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 2.00, 1.00, 1.00, 1.00, 0.50, 2.00, // STE
|
|
1.00, 0.50, 1.00, 1.00, 1.00, 1.00, 2.00, 0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 2.00, 2.00, 0.50, 1.00 // FAI
|
|
];
|
|
|
|
const TYPE_INDEX: Record<TypeName, number> = Object.fromEntries(
|
|
TYPE_NAMES.map((name, i) => [name, i])
|
|
) as Record<TypeName, number>;
|
|
|
|
export const EFFECTIVENESS_MATRIX: number[][] = [];
|
|
for (let i = 0; i < TYPE_NAMES.length; i++) {
|
|
EFFECTIVENESS_MATRIX[i] = EFFECTIVENESS_FLAT.slice(i * 18, (i + 1) * 18);
|
|
}
|
|
|
|
export function getEffectiveness(attackType: TypeName, defenderTypes: TypeName[]): number {
|
|
let result = 1;
|
|
for (const defType of defenderTypes) {
|
|
const attackIdx = TYPE_INDEX[attackType];
|
|
const defIdx = TYPE_INDEX[defType];
|
|
result *= EFFECTIVENESS_MATRIX[attackIdx][defIdx];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
export function getTypeInfo(name: TypeName): TypeInfo {
|
|
return TYPES[findTypeIndex(name)];
|
|
}
|
|
|
|
export function findTypeIndex(name: TypeName): number {
|
|
return TYPE_INDEX[name];
|
|
}
|
|
|
|
export const TYPE_COUNT = TYPES.length;
|