Files
pokerogue-type-pokemon/data/type-data.js
Vectry 6df2002d31 Initial release: PokeRogue Type Effectiveness extension
Chrome/Firefox MV3 extension that shows move type effectiveness during
PokeRogue battles. Features:

- Auto-detects battle state via Phaser game bridge (MAIN world)
- Shows effectiveness multiplier, base power, and physical/special category
- Supports single and double battles
- Manual type calculator mode as fallback
- Draggable overlay with dark theme matching PokeRogue aesthetic
- Settings popup with position, opacity, and display options
- Complete Gen 6+ type chart (18 types) from PokeRogue source data
- Type colors matching PokeRogue's own color scheme
2026-02-12 18:03:09 +00:00

223 lines
6.3 KiB
JavaScript

/**
* PokeRogue Type Data
* Type IDs match PokeRogue's PokemonType enum (src/enums/pokemon-type.ts)
* Type chart derived from PokeRogue's getTypeChartMultiplier (src/data/type.ts)
* Colors from PokeRogue's getTypeRgb (src/data/type.ts)
*/
// Type ID constants matching PokeRogue's enum
const TYPES = {
NORMAL: 0,
FIGHTING: 1,
FLYING: 2,
POISON: 3,
GROUND: 4,
ROCK: 5,
BUG: 6,
GHOST: 7,
STEEL: 8,
FIRE: 9,
WATER: 10,
GRASS: 11,
ELECTRIC: 12,
PSYCHIC: 13,
ICE: 14,
DRAGON: 15,
DARK: 16,
FAIRY: 17
};
// Human-readable names
const TYPE_NAMES = {
0: 'Normal',
1: 'Fighting',
2: 'Flying',
3: 'Poison',
4: 'Ground',
5: 'Rock',
6: 'Bug',
7: 'Ghost',
8: 'Steel',
9: 'Fire',
10: 'Water',
11: 'Grass',
12: 'Electric',
13: 'Psychic',
14: 'Ice',
15: 'Dragon',
16: 'Dark',
17: 'Fairy'
};
// RGB colors from PokeRogue source (getTypeRgb)
const TYPE_COLORS = {
0: [168, 168, 120], // Normal
1: [192, 48, 40], // Fighting
2: [168, 144, 240], // Flying
3: [160, 64, 160], // Poison
4: [224, 192, 104], // Ground
5: [184, 160, 56], // Rock
6: [168, 184, 32], // Bug
7: [112, 88, 152], // Ghost
8: [184, 184, 208], // Steel
9: [240, 128, 48], // Fire
10: [104, 144, 240], // Water
11: [120, 200, 80], // Grass
12: [248, 208, 48], // Electric
13: [248, 88, 136], // Psychic
14: [152, 216, 216], // Ice
15: [112, 56, 248], // Dragon
16: [112, 88, 72], // Dark
17: [232, 136, 200] // Fairy
};
// Move categories matching PokeRogue's MoveCategory enum
const MOVE_CATEGORIES = {
0: 'Physical',
1: 'Special',
2: 'Status'
};
const MOVE_CATEGORY_ICONS = {
0: '\u2694\uFE0F', // Physical - swords
1: '\uD83D\uDD2E', // Special - crystal ball
2: '\u2B50' // Status - star
};
/**
* TYPE_CHART[attackType][defenseType] = multiplier
*
* Derived from PokeRogue's getTypeChartMultiplier() which uses the
* standard Gen 6+ type chart. Only non-1.0 entries are stored;
* missing entries default to 1.0.
*
* Multipliers: 0 (immune), 0.5 (not very effective), 2 (super effective)
* For dual types, multiply both: e.g. 2 * 2 = 4, 2 * 0.5 = 1, etc.
*/
const TYPE_CHART = {
// NORMAL attacking
0: { 5: 0.5, 7: 0, 8: 0.5 },
// FIGHTING attacking
1: { 0: 2, 2: 0.5, 3: 0.5, 5: 2, 6: 0.5, 7: 0, 8: 2, 13: 0.5, 14: 2, 16: 2, 17: 0.5 },
// FLYING attacking
2: { 1: 2, 5: 0.5, 6: 2, 8: 0.5, 11: 2, 12: 0.5 },
// POISON attacking
3: { 3: 0.5, 4: 0.5, 5: 0.5, 7: 0.5, 8: 0, 11: 2, 17: 2 },
// GROUND attacking
4: { 2: 0, 6: 0.5, 3: 2, 5: 2, 8: 2, 9: 2, 11: 0.5, 12: 2 },
// ROCK attacking
5: { 1: 0.5, 2: 2, 4: 0.5, 6: 2, 8: 0.5, 9: 2, 14: 2 },
// BUG attacking
6: { 1: 0.5, 2: 0.5, 3: 0.5, 7: 0.5, 8: 0.5, 9: 0.5, 11: 2, 13: 2, 16: 2, 17: 0.5 },
// GHOST attacking
7: { 0: 0, 7: 2, 13: 2, 16: 0.5 },
// STEEL attacking
8: { 5: 2, 8: 0.5, 9: 0.5, 10: 0.5, 12: 0.5, 14: 2, 17: 2 },
// FIRE attacking
9: { 5: 0.5, 6: 2, 8: 2, 9: 0.5, 10: 0.5, 11: 2, 14: 2, 15: 0.5 },
// WATER attacking
10: { 4: 2, 5: 2, 9: 2, 10: 0.5, 11: 0.5, 15: 0.5 },
// GRASS attacking
11: { 2: 0.5, 3: 0.5, 4: 2, 5: 2, 6: 0.5, 8: 0.5, 9: 0.5, 10: 2, 11: 0.5, 15: 0.5 },
// ELECTRIC attacking
12: { 2: 2, 4: 0, 10: 2, 11: 0.5, 12: 0.5, 15: 0.5 },
// PSYCHIC attacking
13: { 1: 2, 3: 2, 8: 0.5, 13: 0.5, 16: 0 },
// ICE attacking
14: { 2: 2, 4: 2, 8: 0.5, 9: 0.5, 10: 0.5, 11: 2, 14: 0.5, 15: 2 },
// DRAGON attacking
15: { 8: 0.5, 15: 2, 17: 0 },
// DARK attacking
16: { 1: 0.5, 7: 2, 13: 2, 16: 0.5, 17: 0.5 },
// FAIRY attacking
17: { 1: 2, 3: 0.5, 8: 0.5, 9: 0.5, 15: 2, 16: 2 }
};
/**
* Get the effectiveness multiplier for an attack type vs a single defense type.
* @param {number} attackType - Attacker's move type ID
* @param {number} defenseType - Defender's type ID
* @returns {number} Multiplier (0, 0.5, 1, or 2)
*/
function getTypeMult(attackType, defenseType) {
if (attackType < 0 || attackType > 17 || defenseType < 0 || defenseType > 17) {
return 1;
}
const row = TYPE_CHART[attackType];
if (!row || row[defenseType] === undefined) {
return 1;
}
return row[defenseType];
}
/**
* Get effectiveness multiplier for an attack type vs a Pokemon's type(s).
* For dual-type Pokemon, multiplies both matchups.
* @param {number} attackType - Attacker's move type ID
* @param {number[]} defenseTypes - Array of defender's type IDs (1 or 2 types)
* @returns {number} Combined multiplier (0, 0.25, 0.5, 1, 2, or 4)
*/
function getEffectiveness(attackType, defenseTypes) {
if (!defenseTypes || defenseTypes.length === 0) return 1;
let mult = 1;
for (const defType of defenseTypes) {
mult *= getTypeMult(attackType, defType);
}
return mult;
}
/**
* Get a human-readable effectiveness label.
* @param {number} multiplier
* @returns {string}
*/
function getEffectivenessLabel(multiplier) {
if (multiplier === 0) return 'Immune';
if (multiplier === 0.25) return 'Double Resist';
if (multiplier === 0.5) return 'Not Effective';
if (multiplier === 1) return 'Neutral';
if (multiplier === 2) return 'Super Effective';
if (multiplier === 4) return 'Ultra Effective';
return `${multiplier}x`;
}
/**
* Get the CSS color for a type badge background.
* @param {number} typeId
* @returns {string} CSS rgb() color
*/
function getTypeColor(typeId) {
const rgb = TYPE_COLORS[typeId];
if (!rgb) return 'rgb(128, 128, 128)';
return `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`;
}
/**
* Get the CSS color for an effectiveness multiplier (offense coloring).
* Colors from PokeRogue's getTypeDamageMultiplierColor.
* @param {number} multiplier
* @returns {string} Hex color
*/
function getEffectivenessColor(multiplier) {
if (multiplier === 0) return '#929292';
if (multiplier <= 0.25) return '#FF5500';
if (multiplier === 0.5) return '#FE8E00';
if (multiplier === 1) return '#CCCCCC';
if (multiplier === 2) return '#4AA500';
if (multiplier >= 4) return '#52C200';
return '#CCCCCC';
}
/**
* Determine if text on a type badge should be white or dark.
* @param {number} typeId
* @returns {string} 'white' or '#222'
*/
function getTypeBadgeTextColor(typeId) {
const rgb = TYPE_COLORS[typeId];
if (!rgb) return 'white';
// Perceived brightness
const brightness = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000;
return brightness > 160 ? '#222' : 'white';
}