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
This commit is contained in:
222
data/type-data.js
Normal file
222
data/type-data.js
Normal file
@@ -0,0 +1,222 @@
|
||||
/**
|
||||
* 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';
|
||||
}
|
||||
Reference in New Issue
Block a user