unstyled move selector
This commit is contained in:
parent
db1b91c40f
commit
7af3fa3382
2
dist/db/order.json
vendored
2
dist/db/order.json
vendored
File diff suppressed because one or more lines are too long
2
dist/db/pokemon/MAMOSWINE.json
vendored
2
dist/db/pokemon/MAMOSWINE.json
vendored
File diff suppressed because one or more lines are too long
@ -3,7 +3,7 @@ import POGOProtos from 'pogo-protos';
|
|||||||
|
|
||||||
import { ApiService } from 'api/ApiService';
|
import { ApiService } from 'api/ApiService';
|
||||||
|
|
||||||
import { IBaseStatsRank, ICombatMoveStats, IPokemon, TypeEffectiveness, TypeOrder } from 'app/models/Pokemon';
|
import { CombatMoveStats, IBaseStatsRank, IPokemon, TypeEffectiveness, TypeOrder } from 'app/models/Pokemon';
|
||||||
|
|
||||||
import { LegacyMoves } from 'common/models/LegacyMoves';
|
import { LegacyMoves } from 'common/models/LegacyMoves';
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ export const parseGameMaster = async () => {
|
|||||||
const pokemonTypeEffectiveness : Map<POGOProtos.Enums.PokemonType, Map<POGOProtos.Enums.PokemonType, TypeEffectiveness>> = new Map();
|
const pokemonTypeEffectiveness : Map<POGOProtos.Enums.PokemonType, Map<POGOProtos.Enums.PokemonType, TypeEffectiveness>> = new Map();
|
||||||
const pokemonTypeWeaknesses : Map<POGOProtos.Enums.PokemonType, Map<POGOProtos.Enums.PokemonType, TypeEffectiveness>> = new Map();
|
const pokemonTypeWeaknesses : Map<POGOProtos.Enums.PokemonType, Map<POGOProtos.Enums.PokemonType, TypeEffectiveness>> = new Map();
|
||||||
const pokemonTypes : Map<POGOProtos.Enums.PokemonType, Array<number>> = new Map();
|
const pokemonTypes : Map<POGOProtos.Enums.PokemonType, Array<number>> = new Map();
|
||||||
const combatMoves : Map<POGOProtos.Enums.PokemonMove, ICombatMoveStats> = new Map();
|
const combatMoves : CombatMoveStats = new Map();
|
||||||
|
|
||||||
const pokemonBaseStamina : Array<ICalculateRelativeStats> = [];
|
const pokemonBaseStamina : Array<ICalculateRelativeStats> = [];
|
||||||
const pokemonBaseAttack : Array<ICalculateRelativeStats> = [];
|
const pokemonBaseAttack : Array<ICalculateRelativeStats> = [];
|
||||||
@ -141,8 +141,18 @@ export const parseGameMaster = async () => {
|
|||||||
// COMBAT MOVES
|
// COMBAT MOVES
|
||||||
} else if (entry.template_id.indexOf('COMBAT_V') === 0 && entry.combat_move && entry.combat_move.unique_id) {
|
} else if (entry.template_id.indexOf('COMBAT_V') === 0 && entry.combat_move && entry.combat_move.unique_id) {
|
||||||
const combatMoveId = entry.combat_move.unique_id || POGOProtos.Enums.PokemonMove.MOVE_UNSET;
|
const combatMoveId = entry.combat_move.unique_id || POGOProtos.Enums.PokemonMove.MOVE_UNSET;
|
||||||
|
const formatMoveName = (moveId : string) => {
|
||||||
|
const fastMove = '_FAST';
|
||||||
|
const fastMoveIndex = moveId.lastIndexOf(fastMove);
|
||||||
|
let moveName = moveId;
|
||||||
|
if (fastMoveIndex + fastMove.length === moveId.length) {
|
||||||
|
moveName = moveName.substr(0, fastMoveIndex);
|
||||||
|
}
|
||||||
|
return moveName.replace(/_/, ' ').toLowerCase();
|
||||||
|
};
|
||||||
combatMoves.set(combatMoveId, {
|
combatMoves.set(combatMoveId, {
|
||||||
id: combatMoveId,
|
id: combatMoveId,
|
||||||
|
name: formatMoveName(POGOProtos.Enums.PokemonMove[combatMoveId]),
|
||||||
type: entry.combat_move.type || POGOProtos.Enums.PokemonType.POKEMON_TYPE_NONE,
|
type: entry.combat_move.type || POGOProtos.Enums.PokemonType.POKEMON_TYPE_NONE,
|
||||||
power: entry.combat_move.power || 0,
|
power: entry.combat_move.power || 0,
|
||||||
energyDelta: entry.combat_move.energy_delta || 0,
|
energyDelta: entry.combat_move.energy_delta || 0,
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import POGOProtos from 'pogo-protos';
|
|||||||
|
|
||||||
import { AjaxRequest } from 'api/AjaxRequest';
|
import { AjaxRequest } from 'api/AjaxRequest';
|
||||||
|
|
||||||
import { IConfig } from 'app/models/Config';
|
import { IConfig, IConfigJson } from 'app/models/Config';
|
||||||
import { ILeaguePokemon } from 'app/models/League';
|
import { ILeaguePokemon } from 'app/models/League';
|
||||||
import { IPokemon, TypeEffectiveness } from 'app/models/Pokemon';
|
import { IPokemon, TypeEffectiveness } from 'app/models/Pokemon';
|
||||||
|
|
||||||
@ -28,8 +28,11 @@ export class PokemonService implements IPokemonService {
|
|||||||
const queryParameters = {
|
const queryParameters = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const response : IConfig = await this.AjaxRequest.ajaxGet('/dist/db/config.json', queryParameters);
|
const response : IConfigJson = await this.AjaxRequest.ajaxGet('/dist/db/config.json', queryParameters);
|
||||||
return response;
|
return {
|
||||||
|
...response,
|
||||||
|
combatMoves: new Map(response.combatMoves),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getPokemonList() {
|
public async getPokemonList() {
|
||||||
|
|||||||
@ -12,11 +12,12 @@ import { appReducers } from 'app/index';
|
|||||||
|
|
||||||
import * as ActionsPokemonExplorer from 'app/actions';
|
import * as ActionsPokemonExplorer from 'app/actions';
|
||||||
import * as ActionsPokemonSelectList from 'app/components/PokemonSelectList/actions';
|
import * as ActionsPokemonSelectList from 'app/components/PokemonSelectList/actions';
|
||||||
import { IndividualValueKey, IPokemonAppDispatch } from 'app/types';
|
import { IndividualValueKey, IPokemonAppDispatch, ITypeCoverage } from 'app/types';
|
||||||
|
|
||||||
import { Footer } from 'app/components/Footer';
|
import { Footer } from 'app/components/Footer';
|
||||||
import { Header } from 'app/components/Header';
|
import { Header } from 'app/components/Header';
|
||||||
import { LeagueIvExplorer } from 'app/components/LeagueIvExplorer';
|
import { LeagueIvExplorer } from 'app/components/LeagueIvExplorer';
|
||||||
|
import { MovesExplorer } from 'app/components/MovesExplorer';
|
||||||
import { PokemonDisplay } from 'app/components/PokemonDisplay';
|
import { PokemonDisplay } from 'app/components/PokemonDisplay';
|
||||||
import { PokemonSelectList } from 'app/components/PokemonSelectList/PokemonSelectList';
|
import { PokemonSelectList } from 'app/components/PokemonSelectList/PokemonSelectList';
|
||||||
import { TypeEffectiveDisplay } from 'app/components/TypeEffectiveDisplay';
|
import { TypeEffectiveDisplay } from 'app/components/TypeEffectiveDisplay';
|
||||||
@ -35,6 +36,7 @@ interface IConnectedPokemonAppProps extends PokemonAppProps, IPokemonAppDispatch
|
|||||||
export type Navigation = 'pokedex';
|
export type Navigation = 'pokedex';
|
||||||
type SubNavigation = 'pvp' | 'types' | 'moves';
|
type SubNavigation = 'pvp' | 'types' | 'moves';
|
||||||
interface IState {
|
interface IState {
|
||||||
|
isInterruption : boolean;
|
||||||
activeNavigation : Navigation | null;
|
activeNavigation : Navigation | null;
|
||||||
widgets : { [ key in SubNavigation ] : boolean };
|
widgets : { [ key in SubNavigation ] : boolean };
|
||||||
}
|
}
|
||||||
@ -45,6 +47,7 @@ class PokemonApp extends React.Component<IConnectedPokemonAppProps, IState> {
|
|||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
|
isInterruption: false,
|
||||||
activeNavigation: null,
|
activeNavigation: null,
|
||||||
widgets: {
|
widgets: {
|
||||||
pvp: true,
|
pvp: true,
|
||||||
@ -98,13 +101,15 @@ class PokemonApp extends React.Component<IConnectedPokemonAppProps, IState> {
|
|||||||
league,
|
league,
|
||||||
individualValues,
|
individualValues,
|
||||||
leaguePokemon,
|
leaguePokemon,
|
||||||
|
combatMoves,
|
||||||
} = this.props.pokemonExplorerState;
|
} = this.props.pokemonExplorerState;
|
||||||
const {
|
const {
|
||||||
|
isInterruption,
|
||||||
activeNavigation,
|
activeNavigation,
|
||||||
widgets,
|
widgets,
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
|
||||||
const isOverlayShown = activeNavigation === 'pokedex';
|
const isOverlayShown = isInterruption || activeNavigation === 'pokedex';
|
||||||
|
|
||||||
const wrapperCss = classNames(
|
const wrapperCss = classNames(
|
||||||
styles.wrapper,
|
styles.wrapper,
|
||||||
@ -200,6 +205,12 @@ class PokemonApp extends React.Component<IConnectedPokemonAppProps, IState> {
|
|||||||
isHighlighted={ isOverlayShown }
|
isHighlighted={ isOverlayShown }
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
{ widgets.types && leaguePokemon !== null &&
|
||||||
|
<TypeEffectiveDisplay
|
||||||
|
effectiveness={ leaguePokemon.effectiveness }
|
||||||
|
pokemonName={ leaguePokemon.name }
|
||||||
|
/>
|
||||||
|
}
|
||||||
{ widgets.pvp && leaguePokemon !== null &&
|
{ widgets.pvp && leaguePokemon !== null &&
|
||||||
<LeagueIvExplorer
|
<LeagueIvExplorer
|
||||||
activeLeague={ league }
|
activeLeague={ league }
|
||||||
@ -210,13 +221,16 @@ class PokemonApp extends React.Component<IConnectedPokemonAppProps, IState> {
|
|||||||
handleChangeLeague={ this.handleChangeLeague }
|
handleChangeLeague={ this.handleChangeLeague }
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
{ widgets.moves && leaguePokemon !== null &&
|
||||||
|
<MovesExplorer
|
||||||
|
movesById={ combatMoves }
|
||||||
|
quickMoves={ leaguePokemon.moves.quick }
|
||||||
|
chargeMoves={ leaguePokemon.moves.cinematic }
|
||||||
|
handleToggleDropdownOpen={ this.handleToggleInterruption }
|
||||||
|
handleChangeTypeCoverage={ this.handleChangeTypeCoverage }
|
||||||
|
/>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
{ widgets.types && leaguePokemon !== null &&
|
|
||||||
<TypeEffectiveDisplay
|
|
||||||
effectiveness={ leaguePokemon.effectiveness }
|
|
||||||
pokemonName={ leaguePokemon.name }
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
<div className={ leftNavCss }>
|
<div className={ leftNavCss }>
|
||||||
<button className={ pvpButtonCss } onClick={ this.handlePvpClick }><i className={ pvpCss } /></button>
|
<button className={ pvpButtonCss } onClick={ this.handlePvpClick }><i className={ pvpCss } /></button>
|
||||||
<button className={ badgeButtonCss } onClick={ this.handleTypesClick }><i className={ badgeCss } /></button>
|
<button className={ badgeButtonCss } onClick={ this.handleTypesClick }><i className={ badgeCss } /></button>
|
||||||
@ -231,6 +245,12 @@ class PokemonApp extends React.Component<IConnectedPokemonAppProps, IState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly handleToggleInterruption = (isInterruption : boolean) => {
|
||||||
|
this.setState({
|
||||||
|
isInterruption,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private readonly handleOverlayClick = () => {
|
private readonly handleOverlayClick = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
activeNavigation: null,
|
activeNavigation: null,
|
||||||
@ -327,6 +347,10 @@ class PokemonApp extends React.Component<IConnectedPokemonAppProps, IState> {
|
|||||||
this.props.dispatch(ActionsPokemonExplorer.maximizeLevel());
|
this.props.dispatch(ActionsPokemonExplorer.maximizeLevel());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly handleChangeTypeCoverage = (coverage : ITypeCoverage) => {
|
||||||
|
this.props.dispatch(ActionsPokemonExplorer.setTypeCoverage(coverage));
|
||||||
|
}
|
||||||
|
|
||||||
private readonly handleChangeLeagueNavigation = (league : League) => {
|
private readonly handleChangeLeagueNavigation = (league : League) => {
|
||||||
const {
|
const {
|
||||||
history,
|
history,
|
||||||
|
|||||||
@ -1,16 +1,18 @@
|
|||||||
import { action } from 'typesafe-actions';
|
import { action } from 'typesafe-actions';
|
||||||
|
|
||||||
import { PokemonExplorerActionTypes, ThunkResult } from 'app/types';
|
import { ITypeCoverage, PokemonExplorerActionTypes, ThunkResult } from 'app/types';
|
||||||
|
|
||||||
import { calculateMaxLevelForLeague } from 'app/utils/calculator';
|
import { calculateMaxLevelForLeague } from 'app/utils/calculator';
|
||||||
|
|
||||||
import { ILeaguePokemon, League } from 'app/models/League';
|
import { ILeaguePokemon, League } from 'app/models/League';
|
||||||
import { IMaxStats } from 'app/models/Pokemon';
|
import { CombatMoveStats, IMaxStats } from 'app/models/Pokemon';
|
||||||
|
|
||||||
export const setIsLoading = (isLoading : boolean) => action(PokemonExplorerActionTypes.SET_IS_LOADING, { isLoading });
|
export const setIsLoading = (isLoading : boolean) => action(PokemonExplorerActionTypes.SET_IS_LOADING, { isLoading });
|
||||||
|
|
||||||
export const setMaxPossibleStats = (maxStats : IMaxStats) => action(PokemonExplorerActionTypes.SET_MAX_STATS, { maxStats });
|
export const setMaxPossibleStats = (maxStats : IMaxStats) => action(PokemonExplorerActionTypes.SET_MAX_STATS, { maxStats });
|
||||||
|
|
||||||
|
export const setCombatMoveStats = (combatMoves : CombatMoveStats) => action(PokemonExplorerActionTypes.SET_COMBAT_MOVE_STATS, { combatMoves });
|
||||||
|
|
||||||
export const setLeaguePokemon = (leaguePokemon : ILeaguePokemon | null) => action(PokemonExplorerActionTypes.SET_LEAGUE_POKEMON, { leaguePokemon });
|
export const setLeaguePokemon = (leaguePokemon : ILeaguePokemon | null) => action(PokemonExplorerActionTypes.SET_LEAGUE_POKEMON, { leaguePokemon });
|
||||||
|
|
||||||
export const setIvLevel = (level : number | null) => action(PokemonExplorerActionTypes.SET_IV_LEVEL, { level });
|
export const setIvLevel = (level : number | null) => action(PokemonExplorerActionTypes.SET_IV_LEVEL, { level });
|
||||||
@ -23,11 +25,14 @@ export const setIvDef = (ivDef : number | null) => action(PokemonExplorerActionT
|
|||||||
|
|
||||||
export const setActiveLeague = (league : League) => action(PokemonExplorerActionTypes.SET_ACTIVE_LEAGUE, { league });
|
export const setActiveLeague = (league : League) => action(PokemonExplorerActionTypes.SET_ACTIVE_LEAGUE, { league });
|
||||||
|
|
||||||
|
export const setTypeCoverage = (typeCoverage : ITypeCoverage) => action(PokemonExplorerActionTypes.SET_TYPE_COVERAGE, { typeCoverage });
|
||||||
|
|
||||||
export const fetchConfig = (
|
export const fetchConfig = (
|
||||||
) : ThunkResult<Promise<void>> => {
|
) : ThunkResult<Promise<void>> => {
|
||||||
return async (dispatch, getState, extraArguments) => {
|
return async (dispatch, getState, extraArguments) => {
|
||||||
const config = await extraArguments.services.pokemonService.getConfig();
|
const config = await extraArguments.services.pokemonService.getConfig();
|
||||||
dispatch(setMaxPossibleStats(config.maxPossibleStats));
|
dispatch(setMaxPossibleStats(config.maxPossibleStats));
|
||||||
|
dispatch(setCombatMoveStats(config.combatMoves));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -176,7 +176,7 @@ export class LeagueIvExplorer extends React.Component<ILeagueIvExplorerProps, IS
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<div className={ styles.wrapper }>
|
||||||
<LeagueSelector
|
<LeagueSelector
|
||||||
activeLeague={ activeLeague }
|
activeLeague={ activeLeague }
|
||||||
handleLeagueSelect={ handleChangeLeague }
|
handleLeagueSelect={ handleChangeLeague }
|
||||||
@ -252,7 +252,7 @@ export class LeagueIvExplorer extends React.Component<ILeagueIvExplorerProps, IS
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</React.Fragment>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -23,9 +23,9 @@ export interface ILeagueStatsListProps {
|
|||||||
interface IState {
|
interface IState {
|
||||||
activePokemonId : POGOProtos.Enums.PokemonId;
|
activePokemonId : POGOProtos.Enums.PokemonId;
|
||||||
activePokemonForm : POGOProtos.Enums.Form;
|
activePokemonForm : POGOProtos.Enums.Form;
|
||||||
|
hasSetActiveStats : boolean;
|
||||||
listRef : React.RefObject<FixedSizeList>;
|
listRef : React.RefObject<FixedSizeList>;
|
||||||
activeIndex : number;
|
activeIndex : number;
|
||||||
hasSetActiveStats : boolean;
|
|
||||||
dimensions : {
|
dimensions : {
|
||||||
width : number;
|
width : number;
|
||||||
height : number;
|
height : number;
|
||||||
@ -96,8 +96,8 @@ export class LeagueStatsList extends React.Component<ILeagueStatsListProps, ISta
|
|||||||
this.state = {
|
this.state = {
|
||||||
activePokemonId: POGOProtos.Enums.PokemonId.MISSINGNO,
|
activePokemonId: POGOProtos.Enums.PokemonId.MISSINGNO,
|
||||||
activePokemonForm: POGOProtos.Enums.Form.FORM_UNSET,
|
activePokemonForm: POGOProtos.Enums.Form.FORM_UNSET,
|
||||||
listRef: React.createRef(),
|
|
||||||
hasSetActiveStats: false,
|
hasSetActiveStats: false,
|
||||||
|
listRef: React.createRef(),
|
||||||
activeIndex: -1,
|
activeIndex: -1,
|
||||||
dimensions: {
|
dimensions: {
|
||||||
width: -1,
|
width: -1,
|
||||||
@ -159,7 +159,7 @@ export class LeagueStatsList extends React.Component<ILeagueStatsListProps, ISta
|
|||||||
activeIvs.ivHp === stats.ivHp &&
|
activeIvs.ivHp === stats.ivHp &&
|
||||||
activeIvs.ivAtk === stats.ivAtk &&
|
activeIvs.ivAtk === stats.ivAtk &&
|
||||||
activeIvs.ivDef === stats.ivDef,
|
activeIvs.ivDef === stats.ivDef,
|
||||||
highlight: this.state.activeIndex === index,
|
highlight: this.state.activeIndex === index, // this css class currently does nothing
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const onClick = () => {
|
const onClick = () => {
|
||||||
|
|||||||
165
src/ts/app/components/MovesDropdown.tsx
Normal file
165
src/ts/app/components/MovesDropdown.tsx
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
import POGOProtos from 'pogo-protos';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { ContentRect, default as Measure } from 'react-measure';
|
||||||
|
import { FixedSizeList } from 'react-window';
|
||||||
|
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import { CombatMoveStats, IPokemonMove } from 'app/models/Pokemon';
|
||||||
|
|
||||||
|
import { TypeIndicator } from './TypeIndicator';
|
||||||
|
|
||||||
|
import * as styles from 'app/styles/MovesDropdown.scss';
|
||||||
|
|
||||||
|
export interface IMovesDropdownProps {
|
||||||
|
movesById : CombatMoveStats;
|
||||||
|
selectedMove : IPokemonMove | null;
|
||||||
|
options : Array<IPokemonMove>;
|
||||||
|
handleToggleOpen : (open : boolean) => void;
|
||||||
|
handleChangeSelectedOption : (option : IPokemonMove) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IState {
|
||||||
|
isMenuOpen : boolean;
|
||||||
|
listRef : React.RefObject<FixedSizeList>;
|
||||||
|
dimensions : {
|
||||||
|
width : number;
|
||||||
|
height : number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IRowFactory {
|
||||||
|
index : number;
|
||||||
|
style : React.CSSProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MovesDropdown extends React.Component<IMovesDropdownProps, IState> {
|
||||||
|
|
||||||
|
constructor(props : IMovesDropdownProps) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
isMenuOpen: false,
|
||||||
|
listRef: React.createRef(),
|
||||||
|
dimensions: {
|
||||||
|
width: -1,
|
||||||
|
height: -1,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
const {
|
||||||
|
movesById,
|
||||||
|
selectedMove,
|
||||||
|
options,
|
||||||
|
} = this.props;
|
||||||
|
const {
|
||||||
|
isMenuOpen,
|
||||||
|
} = this.state;
|
||||||
|
|
||||||
|
const { width, height } = this.state.dimensions;
|
||||||
|
const onResize = (contentRect : ContentRect) => {
|
||||||
|
if (typeof contentRect.bounds !== 'undefined') {
|
||||||
|
this.setState({ dimensions: contentRect.bounds });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const wrapperCss = classNames(
|
||||||
|
'nes-container',
|
||||||
|
'is-rounded',
|
||||||
|
'nes-select',
|
||||||
|
styles.wrapper,
|
||||||
|
);
|
||||||
|
|
||||||
|
let moveName = 'Select a move';
|
||||||
|
if (selectedMove !== null) {
|
||||||
|
const moveStats = movesById.get(selectedMove.id);
|
||||||
|
if (moveStats) {
|
||||||
|
moveName = moveStats.name;
|
||||||
|
} else {
|
||||||
|
moveName = 'UNKNOWN MOVE';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<div
|
||||||
|
className={ wrapperCss }
|
||||||
|
onClick={ this.toggleMenu }
|
||||||
|
>
|
||||||
|
{ moveName }
|
||||||
|
</div>
|
||||||
|
{ isMenuOpen &&
|
||||||
|
<div>
|
||||||
|
<Measure
|
||||||
|
bounds={ true }
|
||||||
|
onResize={ onResize }
|
||||||
|
>
|
||||||
|
{
|
||||||
|
({ measureRef }) => (
|
||||||
|
<div ref={ measureRef }>
|
||||||
|
<FixedSizeList
|
||||||
|
ref={ this.state.listRef }
|
||||||
|
height={ height }
|
||||||
|
itemCount={ options.length }
|
||||||
|
itemSize={ 35 }
|
||||||
|
width={ width }
|
||||||
|
>
|
||||||
|
{ this.rowFactory.bind(this) }
|
||||||
|
</FixedSizeList>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</Measure>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly toggleMenu = () => {
|
||||||
|
const isMenuOpen = !this.state.isMenuOpen;
|
||||||
|
this.setState({
|
||||||
|
isMenuOpen,
|
||||||
|
});
|
||||||
|
this.props.handleToggleOpen(isMenuOpen);
|
||||||
|
}
|
||||||
|
|
||||||
|
private rowFactory({ index, style } : IRowFactory) {
|
||||||
|
const {
|
||||||
|
movesById,
|
||||||
|
selectedMove,
|
||||||
|
options,
|
||||||
|
} = this.props;
|
||||||
|
const move = options[index];
|
||||||
|
const moveStats = movesById.get(move.id);
|
||||||
|
const css = classNames(
|
||||||
|
'list-item', // global style
|
||||||
|
styles.listItem,
|
||||||
|
{
|
||||||
|
active: selectedMove && selectedMove.id === move.id,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const onClick = () => {
|
||||||
|
this.props.handleChangeSelectedOption(move);
|
||||||
|
this.toggleMenu();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
{ moveStats &&
|
||||||
|
<a
|
||||||
|
key={ index }
|
||||||
|
style={ style }
|
||||||
|
className={ css }
|
||||||
|
onClick={ onClick }
|
||||||
|
>
|
||||||
|
<span>{ moveStats.name }</span>
|
||||||
|
<TypeIndicator type={ moveStats.type } />
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
153
src/ts/app/components/MovesExplorer.tsx
Normal file
153
src/ts/app/components/MovesExplorer.tsx
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import { CombatMoveStats, ICombatMoveStats, IPokemonMove } from 'app/models/Pokemon';
|
||||||
|
|
||||||
|
import { ITypeCoverage } from 'app/types';
|
||||||
|
|
||||||
|
import { MovesDropdown } from 'app/components/MovesDropdown';
|
||||||
|
import { TypeIndicator } from './TypeIndicator';
|
||||||
|
|
||||||
|
import * as styles from 'app/styles/MovesExplorer.scss';
|
||||||
|
|
||||||
|
export interface IMovesExplorerProps {
|
||||||
|
movesById : CombatMoveStats;
|
||||||
|
quickMoves : Array<IPokemonMove>;
|
||||||
|
chargeMoves : Array<IPokemonMove>;
|
||||||
|
handleToggleDropdownOpen : (isOpen : boolean) => void;
|
||||||
|
handleChangeTypeCoverage : (typeCoverage : ITypeCoverage) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IState {
|
||||||
|
quickMove : IPokemonMove | null;
|
||||||
|
chargeMove1 : IPokemonMove | null;
|
||||||
|
chargeMove2 : IPokemonMove | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MovesExplorer extends React.Component<IMovesExplorerProps, IState> {
|
||||||
|
|
||||||
|
constructor(props : IMovesExplorerProps) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
quickMove: null,
|
||||||
|
chargeMove1: null,
|
||||||
|
chargeMove2: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
const {
|
||||||
|
movesById,
|
||||||
|
quickMoves,
|
||||||
|
chargeMoves,
|
||||||
|
handleToggleDropdownOpen,
|
||||||
|
} = this.props;
|
||||||
|
const {
|
||||||
|
quickMove,
|
||||||
|
chargeMove1,
|
||||||
|
chargeMove2,
|
||||||
|
} = this.state;
|
||||||
|
|
||||||
|
const wrapperCss = classNames(
|
||||||
|
'nes-container',
|
||||||
|
styles.wrapper,
|
||||||
|
);
|
||||||
|
|
||||||
|
const quickMoveType = this.getMoveType(quickMove);
|
||||||
|
const chargeMove1Type = this.getMoveType(chargeMove1);
|
||||||
|
const chargeMove2Type = this.getMoveType(chargeMove2);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ wrapperCss }>
|
||||||
|
<MovesDropdown
|
||||||
|
movesById={ movesById }
|
||||||
|
selectedMove={ quickMove }
|
||||||
|
options={ quickMoves }
|
||||||
|
handleToggleOpen={ handleToggleDropdownOpen }
|
||||||
|
handleChangeSelectedOption={ this.handleChangeQuickMove }
|
||||||
|
/>
|
||||||
|
{ quickMove && quickMoveType &&
|
||||||
|
<TypeIndicator type={ quickMoveType } />
|
||||||
|
}
|
||||||
|
<MovesDropdown
|
||||||
|
movesById={ movesById }
|
||||||
|
selectedMove={ chargeMove1 }
|
||||||
|
options={ chargeMoves }
|
||||||
|
handleToggleOpen={ handleToggleDropdownOpen }
|
||||||
|
handleChangeSelectedOption={ this.handleChangeChargeMove1 }
|
||||||
|
/>
|
||||||
|
{ chargeMove1 && chargeMove1Type &&
|
||||||
|
<TypeIndicator type={ chargeMove1Type } />
|
||||||
|
}
|
||||||
|
<MovesDropdown
|
||||||
|
movesById={ movesById }
|
||||||
|
selectedMove={ chargeMove2 }
|
||||||
|
options={ chargeMoves }
|
||||||
|
handleToggleOpen={ handleToggleDropdownOpen }
|
||||||
|
handleChangeSelectedOption={ this.handleChangeChargeMove2 }
|
||||||
|
/>
|
||||||
|
{ chargeMove2 && chargeMove2Type &&
|
||||||
|
<TypeIndicator type={ chargeMove2Type } />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly getMoveType = (move : IPokemonMove | null) => {
|
||||||
|
let moveStats : ICombatMoveStats | null = null;
|
||||||
|
if (move !== null) {
|
||||||
|
moveStats = this.props.movesById.get(move.id) || null;
|
||||||
|
}
|
||||||
|
if (moveStats !== null) {
|
||||||
|
return moveStats.type;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly handleChangeQuickMove = (option : IPokemonMove) => {
|
||||||
|
const {
|
||||||
|
chargeMove1,
|
||||||
|
chargeMove2,
|
||||||
|
} = this.state;
|
||||||
|
this.setState({
|
||||||
|
quickMove: option,
|
||||||
|
});
|
||||||
|
this.props.handleChangeTypeCoverage({
|
||||||
|
type1: this.getMoveType(option),
|
||||||
|
type2: this.getMoveType(chargeMove1),
|
||||||
|
type3: this.getMoveType(chargeMove2),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly handleChangeChargeMove1 = (option : IPokemonMove) => {
|
||||||
|
const {
|
||||||
|
quickMove,
|
||||||
|
chargeMove2,
|
||||||
|
} = this.state;
|
||||||
|
this.setState({
|
||||||
|
chargeMove1: option,
|
||||||
|
});
|
||||||
|
this.props.handleChangeTypeCoverage({
|
||||||
|
type1: this.getMoveType(quickMove),
|
||||||
|
type2: this.getMoveType(option),
|
||||||
|
type3: this.getMoveType(chargeMove2),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly handleChangeChargeMove2 = (option : IPokemonMove) => {
|
||||||
|
const {
|
||||||
|
quickMove,
|
||||||
|
chargeMove1,
|
||||||
|
} = this.state;
|
||||||
|
this.setState({
|
||||||
|
chargeMove2: option,
|
||||||
|
});
|
||||||
|
this.props.handleChangeTypeCoverage({
|
||||||
|
type1: this.getMoveType(quickMove),
|
||||||
|
type2: this.getMoveType(chargeMove1),
|
||||||
|
type3: this.getMoveType(option),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,13 @@
|
|||||||
import { IMaxStats } from 'app/models/Pokemon';
|
import POGOProtos from 'pogo-protos';
|
||||||
|
|
||||||
|
import { CombatMoveStats, ICombatMoveStats, IMaxStats } from 'app/models/Pokemon';
|
||||||
|
|
||||||
|
export interface IConfigJson {
|
||||||
|
maxPossibleStats : IMaxStats;
|
||||||
|
combatMoves : Array<[POGOProtos.Enums.PokemonMove, ICombatMoveStats]>;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IConfig {
|
export interface IConfig {
|
||||||
maxPossibleStats : IMaxStats;
|
maxPossibleStats : IMaxStats;
|
||||||
|
combatMoves : CombatMoveStats;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -65,7 +65,7 @@ export interface IPokemonSpecies {
|
|||||||
genus : string;
|
genus : string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IPokemonMove {
|
export interface IPokemonMove {
|
||||||
id : POGOProtos.Enums.PokemonMove;
|
id : POGOProtos.Enums.PokemonMove;
|
||||||
isLegacy : boolean;
|
isLegacy : boolean;
|
||||||
}
|
}
|
||||||
@ -103,7 +103,10 @@ export interface IStats {
|
|||||||
|
|
||||||
export interface ICombatMoveStats {
|
export interface ICombatMoveStats {
|
||||||
id : POGOProtos.Enums.PokemonMove;
|
id : POGOProtos.Enums.PokemonMove;
|
||||||
|
name : string;
|
||||||
type : POGOProtos.Enums.PokemonType;
|
type : POGOProtos.Enums.PokemonType;
|
||||||
power : number;
|
power : number;
|
||||||
energyDelta : number;
|
energyDelta : number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CombatMoveStats = Map<POGOProtos.Enums.PokemonMove, ICombatMoveStats>;
|
||||||
|
|||||||
@ -21,6 +21,12 @@ export const initialState : IPokemonExplorerState = {
|
|||||||
ivDef: null,
|
ivDef: null,
|
||||||
},
|
},
|
||||||
league: League.GREAT,
|
league: League.GREAT,
|
||||||
|
combatMoves: new Map(),
|
||||||
|
typeCoverage: {
|
||||||
|
type1: null,
|
||||||
|
type2: null,
|
||||||
|
type3: null,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const reduceSetIsLoading = (
|
const reduceSetIsLoading = (
|
||||||
@ -41,6 +47,14 @@ const reduceSetMaxPossibleStats = (
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const reduceSetCombatMoveStats = (
|
||||||
|
state : IPokemonExplorerState,
|
||||||
|
action : ReturnType<typeof Actions.setCombatMoveStats>
|
||||||
|
) : IPokemonExplorerState => ({
|
||||||
|
...state,
|
||||||
|
combatMoves: action.payload.combatMoves,
|
||||||
|
});
|
||||||
|
|
||||||
const reduceSetLeaguePokemon = (
|
const reduceSetLeaguePokemon = (
|
||||||
state : IPokemonExplorerState,
|
state : IPokemonExplorerState,
|
||||||
action : ReturnType<typeof Actions.setLeaguePokemon>
|
action : ReturnType<typeof Actions.setLeaguePokemon>
|
||||||
@ -101,6 +115,16 @@ const reduceSetActiveLeague = (
|
|||||||
league: action.payload.league
|
league: action.payload.league
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const reduceSetTypeCoverage = (
|
||||||
|
state : IPokemonExplorerState,
|
||||||
|
action : ReturnType<typeof Actions.setTypeCoverage>
|
||||||
|
) : IPokemonExplorerState => ({
|
||||||
|
...state,
|
||||||
|
typeCoverage: {
|
||||||
|
...action.payload.typeCoverage
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export const PokemonExplorerReducers : Reducer<IPokemonExplorerState> = (
|
export const PokemonExplorerReducers : Reducer<IPokemonExplorerState> = (
|
||||||
state : IPokemonExplorerState = initialState,
|
state : IPokemonExplorerState = initialState,
|
||||||
action,
|
action,
|
||||||
@ -110,6 +134,8 @@ export const PokemonExplorerReducers : Reducer<IPokemonExplorerState> = (
|
|||||||
return reduceSetIsLoading(state, action as ReturnType<typeof Actions.setIsLoading>);
|
return reduceSetIsLoading(state, action as ReturnType<typeof Actions.setIsLoading>);
|
||||||
case PokemonExplorerActionTypes.SET_MAX_STATS:
|
case PokemonExplorerActionTypes.SET_MAX_STATS:
|
||||||
return reduceSetMaxPossibleStats(state, action as ReturnType<typeof Actions.setMaxPossibleStats>);
|
return reduceSetMaxPossibleStats(state, action as ReturnType<typeof Actions.setMaxPossibleStats>);
|
||||||
|
case PokemonExplorerActionTypes.SET_COMBAT_MOVE_STATS:
|
||||||
|
return reduceSetCombatMoveStats(state, action as ReturnType<typeof Actions.setCombatMoveStats>);
|
||||||
case PokemonExplorerActionTypes.SET_LEAGUE_POKEMON:
|
case PokemonExplorerActionTypes.SET_LEAGUE_POKEMON:
|
||||||
return reduceSetLeaguePokemon(state, action as ReturnType<typeof Actions.setLeaguePokemon>);
|
return reduceSetLeaguePokemon(state, action as ReturnType<typeof Actions.setLeaguePokemon>);
|
||||||
case PokemonExplorerActionTypes.SET_IV_LEVEL:
|
case PokemonExplorerActionTypes.SET_IV_LEVEL:
|
||||||
@ -122,6 +148,8 @@ export const PokemonExplorerReducers : Reducer<IPokemonExplorerState> = (
|
|||||||
return reduceSetIvDef(state, action as ReturnType<typeof Actions.setIvDef>);
|
return reduceSetIvDef(state, action as ReturnType<typeof Actions.setIvDef>);
|
||||||
case PokemonExplorerActionTypes.SET_ACTIVE_LEAGUE:
|
case PokemonExplorerActionTypes.SET_ACTIVE_LEAGUE:
|
||||||
return reduceSetActiveLeague(state, action as ReturnType<typeof Actions.setActiveLeague>);
|
return reduceSetActiveLeague(state, action as ReturnType<typeof Actions.setActiveLeague>);
|
||||||
|
case PokemonExplorerActionTypes.SET_TYPE_COVERAGE:
|
||||||
|
return reduceSetTypeCoverage(state, action as ReturnType<typeof Actions.setTypeCoverage>);
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,10 @@
|
|||||||
@import '~styles/Variables.scss';
|
@import '~styles/Variables.scss';
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
composes: container from './PokemonApp.scss';
|
composes: container from './PokemonApp.scss';
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
|
|||||||
1
src/ts/app/styles/LeagueIvExplorer.scss.d.ts
vendored
1
src/ts/app/styles/LeagueIvExplorer.scss.d.ts
vendored
@ -9,3 +9,4 @@ export const leftColumn: string;
|
|||||||
export const pokemonInfoWrapper: string;
|
export const pokemonInfoWrapper: string;
|
||||||
export const pokemonRankValue: string;
|
export const pokemonRankValue: string;
|
||||||
export const rightColumn: string;
|
export const rightColumn: string;
|
||||||
|
export const wrapper: string;
|
||||||
|
|||||||
7
src/ts/app/styles/MovesDropdown.scss
Normal file
7
src/ts/app/styles/MovesDropdown.scss
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
.wrapper {
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.listItem {
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
4
src/ts/app/styles/MovesDropdown.scss.d.ts
vendored
Normal file
4
src/ts/app/styles/MovesDropdown.scss.d.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
// This file is automatically generated.
|
||||||
|
// Please do not change this file!
|
||||||
|
export const listItem: string;
|
||||||
|
export const wrapper: string;
|
||||||
3
src/ts/app/styles/MovesExplorer.scss
Normal file
3
src/ts/app/styles/MovesExplorer.scss
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.wrapper {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
3
src/ts/app/styles/MovesExplorer.scss.d.ts
vendored
Normal file
3
src/ts/app/styles/MovesExplorer.scss.d.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
// This file is automatically generated.
|
||||||
|
// Please do not change this file!
|
||||||
|
export const wrapper: string;
|
||||||
@ -77,9 +77,14 @@ $overlay-opacity: 0.7;
|
|||||||
.displayWrapper {
|
.displayWrapper {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
// flex-basis: 30rem;
|
// flex-basis: 30rem;
|
||||||
width: 30rem;
|
// width: 30rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column nowrap;
|
flex-flow: column wrap;
|
||||||
|
align-content: center;
|
||||||
|
|
||||||
|
& > * {
|
||||||
|
width: 425px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
@ -90,11 +95,11 @@ $overlay-opacity: 0.7;
|
|||||||
.rightColumn {
|
.rightColumn {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column nowrap;
|
flex-flow: column nowrap;
|
||||||
flex-basis: 45%;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.leftColumn {
|
.leftColumn {
|
||||||
|
width: 45%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import POGOProtos from 'pogo-protos';
|
||||||
|
|
||||||
import { Action } from 'redux';
|
import { Action } from 'redux';
|
||||||
import { ThunkAction, ThunkDispatch } from 'redux-thunk';
|
import { ThunkAction, ThunkDispatch } from 'redux-thunk';
|
||||||
|
|
||||||
@ -6,7 +8,7 @@ import { IProviderExtraArguments } from 'common/models/IProviderExtraArguments';
|
|||||||
import { IPokemonSelectListState } from 'app/components/PokemonSelectList/types';
|
import { IPokemonSelectListState } from 'app/components/PokemonSelectList/types';
|
||||||
|
|
||||||
import { ILeaguePokemon, League } from 'app/models/League';
|
import { ILeaguePokemon, League } from 'app/models/League';
|
||||||
import { IMaxStats } from 'app/models/Pokemon';
|
import { CombatMoveStats, IMaxStats } from 'app/models/Pokemon';
|
||||||
|
|
||||||
import { PokemonService } from 'api/PokemonService';
|
import { PokemonService } from 'api/PokemonService';
|
||||||
|
|
||||||
@ -37,21 +39,31 @@ export interface IIndividualValues {
|
|||||||
ivDef : number | null;
|
ivDef : number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ITypeCoverage {
|
||||||
|
type1 : POGOProtos.Enums.PokemonType | null;
|
||||||
|
type2 : POGOProtos.Enums.PokemonType | null;
|
||||||
|
type3 : POGOProtos.Enums.PokemonType | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IPokemonExplorerState {
|
export interface IPokemonExplorerState {
|
||||||
isLoading : boolean;
|
isLoading : boolean;
|
||||||
leaguePokemon : ILeaguePokemon | null;
|
leaguePokemon : ILeaguePokemon | null;
|
||||||
maxPossibleStats : IMaxStats;
|
maxPossibleStats : IMaxStats;
|
||||||
individualValues : IIndividualValues;
|
individualValues : IIndividualValues;
|
||||||
league : League;
|
league : League;
|
||||||
|
combatMoves : CombatMoveStats;
|
||||||
|
typeCoverage : ITypeCoverage;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PokemonExplorerActionTypes = {
|
export const PokemonExplorerActionTypes = {
|
||||||
SET_IS_LOADING: 'POKEMON_EXPLORER/SET_IS_LOADING',
|
SET_IS_LOADING: 'POKEMON_EXPLORER/SET_IS_LOADING',
|
||||||
SET_MAX_STATS: 'POKEMON_EXPLORER/SET_MAX_STATS',
|
SET_MAX_STATS: 'POKEMON_EXPLORER/SET_MAX_STATS',
|
||||||
|
SET_COMBAT_MOVE_STATS: 'POKEMON_EXPLORER/SET_COMBAT_MOVE_STATS',
|
||||||
SET_LEAGUE_POKEMON: 'POKEMON_EXPLORER/SET_LEAGUE_POKEMON',
|
SET_LEAGUE_POKEMON: 'POKEMON_EXPLORER/SET_LEAGUE_POKEMON',
|
||||||
SET_IV_LEVEL: 'POKEMON_EXPLORER/SET_IV_LEVEL',
|
SET_IV_LEVEL: 'POKEMON_EXPLORER/SET_IV_LEVEL',
|
||||||
SET_IV_HP: 'POKEMON_EXPLORER/SET_IV_HP',
|
SET_IV_HP: 'POKEMON_EXPLORER/SET_IV_HP',
|
||||||
SET_IV_ATK: 'POKEMON_EXPLORER/SET_IV_ATK',
|
SET_IV_ATK: 'POKEMON_EXPLORER/SET_IV_ATK',
|
||||||
SET_IV_DEF: 'POKEMON_EXPLORER/SET_IV_DEF',
|
SET_IV_DEF: 'POKEMON_EXPLORER/SET_IV_DEF',
|
||||||
SET_ACTIVE_LEAGUE: 'POKEMON_EXPLORER/SET_ACTIVE_LEAGUE',
|
SET_ACTIVE_LEAGUE: 'POKEMON_EXPLORER/SET_ACTIVE_LEAGUE',
|
||||||
|
SET_TYPE_COVERAGE: 'POKEMON_EXPLORER/SET_TYPE_COVERAGE',
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user