prepare for league switching
This commit is contained in:
parent
0abda4387f
commit
a639613694
@ -2,17 +2,16 @@ import * as fs from 'fs';
|
||||
import PokemonDescription from 'pokemongo-json-pokedex/output/locales/en-US/pokemon.json';
|
||||
import Pokemon from 'pokemongo-json-pokedex/output/pokemon.json';
|
||||
|
||||
import { ILeaguePokemon, IMaxCpByLeague, League, MaxCpByLeague } from 'app/models/League';
|
||||
import { LevelMultipliers } from 'app/models/LevelMultipliers';
|
||||
import { Grade, IBaseStatsRank, ILeaguePokemon, IMaxStats, IPokemon, IStats, League, PokemonId, Type } from 'app/models/Pokemon';
|
||||
import { Grade, IBaseStatsRank, IMaxStats, IPokemon, IStats, PokemonId, Type } from 'app/models/Pokemon';
|
||||
|
||||
type ICpAndTotalFound = Record<number, Array<IStats>>;
|
||||
interface IStatsDistribution {
|
||||
great : ICpAndTotalFound;
|
||||
ultra : ICpAndTotalFound;
|
||||
}
|
||||
interface IMaxCpByLeague {
|
||||
great : number;
|
||||
ultra : number;
|
||||
master : ICpAndTotalFound;
|
||||
custom : ICpAndTotalFound;
|
||||
}
|
||||
interface ICalculateRelativeStats {
|
||||
id : string;
|
||||
@ -21,11 +20,6 @@ interface ICalculateRelativeStats {
|
||||
|
||||
const outPath = './dist/db/';
|
||||
|
||||
const maxCpByLeague : IMaxCpByLeague = {
|
||||
great: 1500,
|
||||
ultra: 2500
|
||||
};
|
||||
|
||||
const maxPossibleStats : IMaxStats = {
|
||||
baseStamina: 0,
|
||||
baseAttack: 0,
|
||||
@ -140,6 +134,8 @@ Pokemon.forEach((mon) => {
|
||||
pvp: {
|
||||
great: [],
|
||||
ultra: [],
|
||||
master: [],
|
||||
custom: [],
|
||||
},
|
||||
};
|
||||
|
||||
@ -183,6 +179,8 @@ Pokemon.forEach((mon) => {
|
||||
const combinedStatsDistribution : IStatsDistribution = {
|
||||
great: {},
|
||||
ultra: {},
|
||||
master: {},
|
||||
custom: {},
|
||||
};
|
||||
for (let ivHp = 15; ivHp >= 0; ivHp--) {
|
||||
for (let ivAtk = 15; ivAtk >= 0; ivAtk--) {
|
||||
@ -190,9 +188,9 @@ Pokemon.forEach((mon) => {
|
||||
let pokemonWithIvs : IStats;
|
||||
const cpMultiplier = (baseAtk + ivAtk) * Math.sqrt(baseDef + ivDef) * Math.sqrt(baseHp + ivHp);
|
||||
|
||||
Object.keys(maxCpByLeague).forEach((key) => {
|
||||
Object.keys(MaxCpByLeague).forEach((key) => {
|
||||
const league = key as League;
|
||||
const maxCp = maxCpByLeague[league];
|
||||
const maxCp = MaxCpByLeague[league];
|
||||
const maxLeagueLevelMultiplierIndex = getClosestCpMultiplierIndex(Math.sqrt((maxCp * 10) / cpMultiplier));
|
||||
const maxLeagueLevelMultiplier = LevelMultipliers[maxLeagueLevelMultiplierIndex];
|
||||
const maxLeagueCp = Math.floor((cpMultiplier * Math.pow(maxLeagueLevelMultiplier, 2)) / 10);
|
||||
|
||||
@ -46,40 +46,124 @@ $main-border-color: $gray-scale-4;
|
||||
|
||||
$main-hover-color: darken($main-background-color, 5%);
|
||||
|
||||
$great-league-color: #4d6ed0;
|
||||
$ultra-league-color: #5e30a3;
|
||||
$master-league-color: #475b5e;
|
||||
$custom-league-color: #f00;
|
||||
$league-colors: (
|
||||
great: (
|
||||
primary: $great-league-color,
|
||||
border: $nes-dark,
|
||||
hover: lighten($great-league-color, 10),
|
||||
// active: #355aca,
|
||||
blur: lighten($great-league-color, 30),
|
||||
blur-border: lighten($nes-dark, 10),
|
||||
shadow: #1a3ea7,
|
||||
contrast: #fff
|
||||
),
|
||||
ultra: (
|
||||
primary: $ultra-league-color,
|
||||
border: $nes-dark,
|
||||
hover: lighten($ultra-league-color, 10),
|
||||
// active: #50298b,
|
||||
blur: lighten($ultra-league-color, 30),
|
||||
blur-border: lighten($nes-dark, 10),
|
||||
shadow: #342085,
|
||||
contrast: #fff
|
||||
),
|
||||
master: (
|
||||
primary: $master-league-color,
|
||||
border: $nes-dark,
|
||||
hover: lighten($master-league-color, 10),
|
||||
// active: #3a4a4d,
|
||||
blur: lighten($master-league-color, 30),
|
||||
blur-border: lighten($nes-dark, 10),
|
||||
shadow: #2f4947,
|
||||
contrast: #fff
|
||||
),
|
||||
custom: (
|
||||
primary: $custom-league-color,
|
||||
border: $nes-dark,
|
||||
hover: lighten($custom-league-color, 10),
|
||||
blur: lighten($custom-league-color, 30),
|
||||
blur-border: lighten($nes-dark, 10),
|
||||
shadow: darkred,
|
||||
contrast: #fff
|
||||
)
|
||||
);
|
||||
|
||||
// https://bulbapedia.bulbagarden.net/wiki/Category:Type_color_templates
|
||||
$normal-primary: #a8a878;
|
||||
$normal-contrast: #fff;
|
||||
$fire-primary: #f08030;
|
||||
$fire-contrast: #fff;
|
||||
$fighting-primary: #c03028;
|
||||
$fighting-contrast: #fff;
|
||||
$water-primary: #6890f0;
|
||||
$water-contrast: #fff;
|
||||
$flying-primary: #a890f0;
|
||||
$flying-contrast: #fff;
|
||||
$grass-primary: #78c850;
|
||||
$grass-contrast: #fff;
|
||||
$poison-primary: #a040a0;
|
||||
$poison-contrast: #fff;
|
||||
$electric-primary: #f8d030;
|
||||
$electric-contrast: #fff;
|
||||
$ground-primary: #e0c068;
|
||||
$ground-contrast: #fff;
|
||||
$psychic-primary: #f85888;
|
||||
$psychic-contrast: #fff;
|
||||
$rock-primary: #b8a038;
|
||||
$rock-contrast: #fff;
|
||||
$ice-primary: #98d8d8;
|
||||
$ice-contrast: #fff;
|
||||
$bug-primary: #a8b820;
|
||||
$bug-contrast: #fff;
|
||||
$dragon-primary: #6f35fc;
|
||||
$dragon-contrast: #fff;
|
||||
$ghost-primary: #705898;
|
||||
$ghost-contrast: #fff;
|
||||
$dark-primary: #705848;
|
||||
$dark-contrast: #fff;
|
||||
$steel-primary: #b8b8d0;
|
||||
$steel-contrast: #fff;
|
||||
$fairy-primary: #ee99ac;
|
||||
$fairy-contrast: #fff;
|
||||
$type-colors: (
|
||||
normal: (
|
||||
primary: #a8a878,
|
||||
contrast: #fff
|
||||
),
|
||||
fire: (
|
||||
primary: #f08030,
|
||||
contrast: #fff
|
||||
),
|
||||
fighting: (
|
||||
primary: #c03028,
|
||||
contrast: #fff
|
||||
),
|
||||
water: (
|
||||
primary: #6890f0,
|
||||
contrast: #fff
|
||||
),
|
||||
flying: (
|
||||
primary: #a890f0,
|
||||
contrast: #fff
|
||||
),
|
||||
grass: (
|
||||
primary: #78c850,
|
||||
contrast: #fff
|
||||
),
|
||||
poison: (
|
||||
primary: #a040a0,
|
||||
contrast: #fff
|
||||
),
|
||||
electric: (
|
||||
primary: #f8d030,
|
||||
contrast: #fff
|
||||
),
|
||||
ground: (
|
||||
primary: #e0c068,
|
||||
contrast: #fff
|
||||
),
|
||||
psychic: (
|
||||
primary: #f85888,
|
||||
contrast: #fff
|
||||
),
|
||||
rock: (
|
||||
primary: #b8a038,
|
||||
contrast: #fff
|
||||
),
|
||||
ice: (
|
||||
primary: #98d8d8,
|
||||
contrast: #fff
|
||||
),
|
||||
bug: (
|
||||
primary: #a8b820,
|
||||
contrast: #fff
|
||||
),
|
||||
dragon: (
|
||||
primary: #6f35fc,
|
||||
contrast: #fff
|
||||
),
|
||||
ghost: (
|
||||
primary: #705898,
|
||||
contrast: #fff
|
||||
),
|
||||
dark: (
|
||||
primary: #705848,
|
||||
contrast: #fff
|
||||
),
|
||||
steel: (
|
||||
primary: #b8b8d0,
|
||||
contrast: #fff
|
||||
),
|
||||
fairy: (
|
||||
primary: #ee99ac,
|
||||
contrast: #fff
|
||||
)
|
||||
);
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { AjaxUtils } from 'api/AjaxUtils';
|
||||
|
||||
import { IConfig } from 'app/models/Config';
|
||||
import { ILeaguePokemon, IPokemon, League } from 'app/models/Pokemon';
|
||||
import { ILeaguePokemon, League } from 'app/models/League';
|
||||
import { IPokemon } from 'app/models/Pokemon';
|
||||
|
||||
interface IPokemonJSON extends IPokemon {}
|
||||
interface ILeaguePokemonJSON extends ILeaguePokemon {}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { League } from 'app/models/League';
|
||||
|
||||
import { appReducers } from './index';
|
||||
|
||||
import * as ActionsPokemonExplorer from './components/PokemonExplorer/actions';
|
||||
@ -43,6 +45,7 @@ class PokemonApp extends React.Component<IConnectedPokemonAppProps> {
|
||||
filterTerm,
|
||||
} = this.props.pokemonSelectListState;
|
||||
const {
|
||||
league,
|
||||
individualValues,
|
||||
leaguePokemon,
|
||||
} = this.props.pokemonExplorerState;
|
||||
@ -60,10 +63,12 @@ class PokemonApp extends React.Component<IConnectedPokemonAppProps> {
|
||||
{ leaguePokemon !== null &&
|
||||
<PokemonExplorer
|
||||
isLoading={ this.props.pokemonExplorerState.isLoading }
|
||||
activeLeague={ league }
|
||||
leaguePokemon={ leaguePokemon }
|
||||
individualValues={ individualValues }
|
||||
handleChangeIndividualValue={ this.handleChangeIndividualValue }
|
||||
handleMaximizeLevel={ this.handleMaximizeLevel }
|
||||
handleChangeLeague={ this.handleChangeLeague }
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
@ -118,6 +123,10 @@ class PokemonApp extends React.Component<IConnectedPokemonAppProps> {
|
||||
private readonly handleMaximizeLevel = () => {
|
||||
this.props.dispatch(ActionsPokemonExplorer.maximizeLevel());
|
||||
}
|
||||
|
||||
private readonly handleChangeLeague = (league : League) => {
|
||||
this.props.dispatch(ActionsPokemonExplorer.setActiveLeague(league));
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state : ReturnType<typeof appReducers>) : PokemonAppProps => {
|
||||
|
||||
54
src/ts/app/components/PokemonExplorer/LeagueSelector.tsx
Normal file
54
src/ts/app/components/PokemonExplorer/LeagueSelector.tsx
Normal file
@ -0,0 +1,54 @@
|
||||
import React from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { League, LeagueLabels } from 'app/models/League';
|
||||
|
||||
import * as styles from './styles/LeagueSelector.scss';
|
||||
|
||||
export interface ILeagueSelectorProps {
|
||||
activeLeague : League;
|
||||
handleLeagueSelect : (league : League) => void;
|
||||
}
|
||||
|
||||
export class LeagueSelector extends React.Component<ILeagueSelectorProps, object> {
|
||||
|
||||
public render() {
|
||||
const { activeLeague } = this.props;
|
||||
|
||||
const css = classNames(
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={ styles.wrapper }>
|
||||
{
|
||||
LeagueLabels.map((league, index) => {
|
||||
const buttonCss = classNames(
|
||||
'nes-btn',
|
||||
{
|
||||
[ styles.greatLeagueButton ]: league.id === 'great',
|
||||
[ styles.ultraLeagueButton ]: league.id === 'ultra',
|
||||
[ styles.masterLeagueButton ]: league.id === 'master',
|
||||
[ styles.customLeagueButton ]: league.id === 'custom',
|
||||
[ styles.active ]: activeLeague === league.id,
|
||||
}
|
||||
);
|
||||
return <button
|
||||
key={ league.id + index }
|
||||
className={ buttonCss }
|
||||
onClick={ this.handleLeagueSelectFactory(league.id) }
|
||||
>
|
||||
{ league.label }
|
||||
</button>;
|
||||
})
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private readonly handleLeagueSelectFactory = (league : League) => {
|
||||
return () => {
|
||||
this.props.handleLeagueSelect(league);
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -2,12 +2,14 @@ import React from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { Grade, ILeaguePokemon, IMaxStats, IStats, } from 'app/models/Pokemon';
|
||||
import { ILeaguePokemon, League } from 'app/models/League';
|
||||
import { Grade, IStats, } from 'app/models/Pokemon';
|
||||
import { calculateCp, calculateStatAtLevel } from 'app/utils/calculator';
|
||||
import { formatDexNumber } from 'app/utils/formatter';
|
||||
|
||||
import { IIndividualValues, IndividualValueKey } from './types';
|
||||
|
||||
import { LeagueSelector } from './LeagueSelector';
|
||||
import { LeagueStatsList } from './LeagueStatsList';
|
||||
import { StatDisplay } from './StatDisplay';
|
||||
|
||||
@ -15,11 +17,13 @@ import * as styles from './styles/PokemonExplorer.scss';
|
||||
|
||||
export interface IPokemonExplorerProps {
|
||||
isLoading : boolean;
|
||||
activeLeague : League;
|
||||
leaguePokemon : ILeaguePokemon;
|
||||
individualValues : IIndividualValues;
|
||||
|
||||
handleChangeIndividualValue : (stat : IndividualValueKey, value : number | null) => void;
|
||||
handleMaximizeLevel : () => void;
|
||||
handleChangeLeague : (league : League) => void;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
@ -54,6 +58,7 @@ export class PokemonExplorer extends React.Component<IPokemonExplorerProps, ISta
|
||||
|
||||
public render() {
|
||||
const {
|
||||
activeLeague,
|
||||
individualValues,
|
||||
leaguePokemon
|
||||
} = this.props;
|
||||
@ -236,6 +241,10 @@ export class PokemonExplorer extends React.Component<IPokemonExplorerProps, ISta
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<LeagueSelector
|
||||
activeLeague={ activeLeague }
|
||||
handleLeagueSelect={ this.handleLeagueSelect }
|
||||
/>
|
||||
<section className={ formContainerCss }>
|
||||
<h5 className={ containerTitleCss }>IVs</h5>
|
||||
<div className={ inlineFieldCss }>
|
||||
@ -379,4 +388,8 @@ export class PokemonExplorer extends React.Component<IPokemonExplorerProps, ISta
|
||||
handleChangeIndividualValue('atk', stats.ivAtk);
|
||||
handleChangeIndividualValue('def', stats.ivDef);
|
||||
}
|
||||
|
||||
private readonly handleLeagueSelect = (league : League) => {
|
||||
this.props.handleChangeLeague(league);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ import React from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import * as styles from './styles/PokemonExplorer.scss';
|
||||
import * as styles from './styles/StatDisplay.scss';
|
||||
|
||||
export interface IStartDisplayProps {
|
||||
statLabel : string;
|
||||
|
||||
@ -5,7 +5,8 @@ import { PokemonExplorerActionTypes } from './types';
|
||||
|
||||
import { calculateMaxLevelForLeague } from 'app/utils/calculator';
|
||||
|
||||
import { ILeaguePokemon, IMaxStats } from 'app/models/Pokemon';
|
||||
import { ILeaguePokemon, League } from 'app/models/League';
|
||||
import { IMaxStats } from 'app/models/Pokemon';
|
||||
|
||||
export const setIsLoading = (isLoading : boolean) => action(PokemonExplorerActionTypes.SET_IS_LOADING, { isLoading });
|
||||
|
||||
@ -21,6 +22,8 @@ export const setIvAtk = (atk : number | null) => action(PokemonExplorerActionTyp
|
||||
|
||||
export const setIvDef = (def : number | null) => action(PokemonExplorerActionTypes.SET_IV_DEF, { def });
|
||||
|
||||
export const setActiveLeague = (league : League) => action(PokemonExplorerActionTypes.SET_ACTIVE_LEAGUE, { league });
|
||||
|
||||
export const fetchConfig = (
|
||||
) : ThunkResult<Promise<void>> => {
|
||||
return async (dispatch, getState, extraArguments) => {
|
||||
|
||||
@ -91,6 +91,14 @@ const reduceSetIvDef = (
|
||||
}
|
||||
});
|
||||
|
||||
const reduceSetActiveLeague = (
|
||||
state : IPokemonExplorerState,
|
||||
action : ReturnType<typeof Actions.setActiveLeague>
|
||||
) : IPokemonExplorerState => ({
|
||||
...state,
|
||||
league: action.payload.league
|
||||
});
|
||||
|
||||
export const PokemonExplorerReducers : Reducer<IPokemonExplorerState> = (
|
||||
state : IPokemonExplorerState = initialState,
|
||||
action,
|
||||
@ -110,6 +118,8 @@ export const PokemonExplorerReducers : Reducer<IPokemonExplorerState> = (
|
||||
return reduceSetIvAtk(state, action as ReturnType<typeof Actions.setIvAtk>);
|
||||
case PokemonExplorerActionTypes.SET_IV_DEF:
|
||||
return reduceSetIvDef(state, action as ReturnType<typeof Actions.setIvDef>);
|
||||
case PokemonExplorerActionTypes.SET_ACTIVE_LEAGUE:
|
||||
return reduceSetActiveLeague(state, action as ReturnType<typeof Actions.setActiveLeague>);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -0,0 +1,76 @@
|
||||
@import 'styles/Variables.scss';
|
||||
|
||||
@each $league, $colors in $league-colors {
|
||||
$blur: map-get($colors, 'blur');
|
||||
$hover: map-get($colors, 'hover');
|
||||
$primary: map-get($colors, 'primary');
|
||||
$shadow: map-get($colors, 'shadow');
|
||||
$border: map-get($colors, 'border');
|
||||
$blur-border: map-get($colors, 'blur-border');
|
||||
$contrast: map-get($colors, 'contrast');
|
||||
|
||||
:global(.nes-btn).#{$league}LeagueButton {
|
||||
color: $contrast;
|
||||
background-color: $blur;
|
||||
box-shadow: none;
|
||||
// box-shadow: inset -4px -4px darken(saturate(adjust-hue($primary, -12deg), 7), 9);
|
||||
// box-shadow: inset -4px -4px darken(saturate($primary, 14), 18);
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
border-color: $blur-border;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: $hover;
|
||||
box-shadow: inset -4px -4px $shadow;
|
||||
|
||||
&:active {
|
||||
box-shadow: inset 4px 4px $shadow;
|
||||
}
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
border-color: $border;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: $primary;
|
||||
box-shadow: inset -4px -4px $shadow;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
box-shadow: inset -6px -6px $shadow;
|
||||
}
|
||||
|
||||
&:active {
|
||||
box-shadow: inset 4px 4px $shadow;
|
||||
}
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
border-color: $border;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: above won't generate an scss file automatically...
|
||||
|
||||
/* stylelint-disable block-no-empty */
|
||||
.greatLeagueButton,
|
||||
.ultraLeagueButton,
|
||||
.masterLeagueButton,
|
||||
.customLeagueButton {
|
||||
font-size: 1em;
|
||||
}
|
||||
/* stylelint-enable block-no-empty */
|
||||
|
||||
.wrapper {
|
||||
font-size: 0.8em;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
8
src/ts/app/components/PokemonExplorer/styles/LeagueSelector.scss.d.ts
vendored
Normal file
8
src/ts/app/components/PokemonExplorer/styles/LeagueSelector.scss.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
// This file is automatically generated.
|
||||
// Please do not change this file!
|
||||
export const active: string;
|
||||
export const customLeagueButton: string;
|
||||
export const greatLeagueButton: string;
|
||||
export const masterLeagueButton: string;
|
||||
export const ultraLeagueButton: string;
|
||||
export const wrapper: string;
|
||||
@ -76,165 +76,17 @@
|
||||
box-shadow: 0 -4px $shadow-color, 0 -8px, 4px 0 $shadow-color, 4px -4px, 8px 0, 0 4px $shadow-color, 0 8px, -4px 0 $shadow-color, -4px 4px, -8px 0, -4px -4px, 4px 4px;
|
||||
}
|
||||
|
||||
&:global(.normal) {
|
||||
color: $normal-contrast;
|
||||
background-color: $normal-primary;
|
||||
@each $type, $colors in $type-colors {
|
||||
$primary: map-get($colors, 'primary');
|
||||
$contrast: map-get($colors, 'contrast');
|
||||
|
||||
&::after {
|
||||
@include rounded-box-shadow($normal-primary);
|
||||
}
|
||||
}
|
||||
&:global(.#{$type}) {
|
||||
color: $contrast;
|
||||
background-color: $primary;
|
||||
|
||||
&:global(.fire) {
|
||||
color: $fire-contrast;
|
||||
background-color: $fire-primary;
|
||||
|
||||
&::after {
|
||||
@include rounded-box-shadow($fire-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&:global(.fighting) {
|
||||
color: $fighting-contrast;
|
||||
background-color: $fighting-primary;
|
||||
|
||||
&::after {
|
||||
@include rounded-box-shadow($fighting-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&:global(.water) {
|
||||
color: $water-contrast;
|
||||
background-color: $water-primary;
|
||||
|
||||
&::after {
|
||||
@include rounded-box-shadow($water-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&:global(.flying) {
|
||||
color: $flying-contrast;
|
||||
background-color: $flying-primary;
|
||||
|
||||
&::after {
|
||||
@include rounded-box-shadow($flying-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&:global(.grass) {
|
||||
color: $grass-contrast;
|
||||
background-color: $grass-primary;
|
||||
|
||||
&::after {
|
||||
@include rounded-box-shadow($grass-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&:global(.poison) {
|
||||
color: $poison-contrast;
|
||||
background-color: $poison-primary;
|
||||
|
||||
&::after {
|
||||
@include rounded-box-shadow($poison-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&:global(.electric) {
|
||||
color: $electric-contrast;
|
||||
background-color: $electric-primary;
|
||||
|
||||
&::after {
|
||||
@include rounded-box-shadow($electric-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&:global(.ground) {
|
||||
color: $ground-contrast;
|
||||
background-color: $ground-primary;
|
||||
|
||||
&::after {
|
||||
@include rounded-box-shadow($ground-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&:global(.psychic) {
|
||||
color: $psychic-contrast;
|
||||
background-color: $psychic-primary;
|
||||
|
||||
&::after {
|
||||
@include rounded-box-shadow($psychic-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&:global(.rock) {
|
||||
color: $rock-contrast;
|
||||
background-color: $rock-primary;
|
||||
|
||||
&::after {
|
||||
@include rounded-box-shadow($rock-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&:global(.ice) {
|
||||
color: $ice-contrast;
|
||||
background-color: $ice-primary;
|
||||
|
||||
&::after {
|
||||
@include rounded-box-shadow($ice-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&:global(.bug) {
|
||||
color: $bug-contrast;
|
||||
background-color: $bug-primary;
|
||||
|
||||
&::after {
|
||||
@include rounded-box-shadow($bug-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&:global(.dragon) {
|
||||
color: $dragon-contrast;
|
||||
background-color: $dragon-primary;
|
||||
|
||||
&::after {
|
||||
@include rounded-box-shadow($dragon-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&:global(.ghost) {
|
||||
color: $ghost-contrast;
|
||||
background-color: $ghost-primary;
|
||||
|
||||
&::after {
|
||||
@include rounded-box-shadow($ghost-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&:global(.dark) {
|
||||
color: $dark-contrast;
|
||||
background-color: $dark-primary;
|
||||
|
||||
&::after {
|
||||
@include rounded-box-shadow($dark-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&:global(.steel) {
|
||||
color: $steel-contrast;
|
||||
background-color: $steel-primary;
|
||||
|
||||
&::after {
|
||||
@include rounded-box-shadow($steel-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&:global(.fairy) {
|
||||
color: $fairy-contrast;
|
||||
background-color: $fairy-primary;
|
||||
|
||||
&::after {
|
||||
@include rounded-box-shadow($fairy-primary);
|
||||
&::after {
|
||||
@include rounded-box-shadow($primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -254,23 +106,6 @@
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.baseStatRow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
& > * {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
& > progress {
|
||||
flex-shrink: 1;
|
||||
margin-left: 1em;
|
||||
width: 5em;
|
||||
height: 0.5em;
|
||||
padding: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
:global(.nes-field.is-inline) .ivInput {
|
||||
width: 4.25em;
|
||||
padding-left: 0.7em;
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
// This file is automatically generated.
|
||||
// Please do not change this file!
|
||||
export const baseStatRow: string;
|
||||
export const dexHeader: string;
|
||||
export const fieldRow: string;
|
||||
export const formHeader: string;
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
.baseStatRow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
& > * {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
& > progress {
|
||||
flex-shrink: 1;
|
||||
margin-left: 1em;
|
||||
width: 5em;
|
||||
height: 0.5em;
|
||||
padding: 2px;
|
||||
}
|
||||
}
|
||||
3
src/ts/app/components/PokemonExplorer/styles/StatDisplay.scss.d.ts
vendored
Normal file
3
src/ts/app/components/PokemonExplorer/styles/StatDisplay.scss.d.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
// This file is automatically generated.
|
||||
// Please do not change this file!
|
||||
export const baseStatRow: string;
|
||||
@ -1,4 +1,5 @@
|
||||
import { ILeaguePokemon, IMaxStats, League } from 'app/models/Pokemon';
|
||||
import { ILeaguePokemon, League } from 'app/models/League';
|
||||
import { IMaxStats } from 'app/models/Pokemon';
|
||||
|
||||
export type IndividualValueKey = 'level' | 'hp' | 'atk' | 'def';
|
||||
export interface IIndividualValues {
|
||||
@ -24,4 +25,5 @@ export const PokemonExplorerActionTypes = {
|
||||
SET_IV_HP: 'POKEMON_EXPLORER/SET_IV_HP',
|
||||
SET_IV_ATK: 'POKEMON_EXPLORER/SET_IV_ATK',
|
||||
SET_IV_DEF: 'POKEMON_EXPLORER/SET_IV_DEF',
|
||||
SET_ACTIVE_LEAGUE: 'POKEMON_EXPLORER/SET_ACTIVE_LEAGUE',
|
||||
};
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { action } from 'typesafe-actions';
|
||||
|
||||
import { ILeaguePokemon, IPokemon } from 'app/models/Pokemon';
|
||||
import { ILeaguePokemon } from 'app/models/League';
|
||||
import { IPokemon } from 'app/models/Pokemon';
|
||||
|
||||
import { ThunkResult } from 'app/types';
|
||||
import { PokemonSelectListActionTypes } from './types';
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { ILeaguePokemon, IPokemon } from 'app/models/Pokemon';
|
||||
import { ILeaguePokemon } from 'app/models/League';
|
||||
import { IPokemon } from 'app/models/Pokemon';
|
||||
|
||||
export interface IPokemonSelectListState {
|
||||
isLoading : boolean;
|
||||
|
||||
40
src/ts/app/models/League.ts
Normal file
40
src/ts/app/models/League.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { IPokemon, IStats } from './Pokemon';
|
||||
|
||||
export type League = 'great' | 'ultra' | 'master' | 'custom';
|
||||
|
||||
export interface IMaxCpByLeague {
|
||||
great : number;
|
||||
ultra : number;
|
||||
master : number;
|
||||
custom : number;
|
||||
}
|
||||
|
||||
export const MaxCpByLeague : IMaxCpByLeague = {
|
||||
great: 1500,
|
||||
ultra: 2500,
|
||||
master: Infinity,
|
||||
custom: Infinity,
|
||||
};
|
||||
|
||||
export const LeagueLabels : Array<{ id : League, label : string }> = [{
|
||||
id: 'great',
|
||||
label: 'Great'
|
||||
}, {
|
||||
id: 'ultra',
|
||||
label: 'Ultra'
|
||||
}, {
|
||||
id: 'master',
|
||||
label: 'Master'
|
||||
}, {
|
||||
id: 'custom',
|
||||
label: 'Custom'
|
||||
}];
|
||||
|
||||
export interface ILeaguePokemon extends IPokemon {
|
||||
pvp : {
|
||||
great : Array<IStats>;
|
||||
ultra : Array<IStats>;
|
||||
master : Array<IStats>;
|
||||
custom : Array<IStats>;
|
||||
};
|
||||
}
|
||||
@ -38,13 +38,6 @@ export interface IPokemon {
|
||||
stats : IBaseStats;
|
||||
statsRank : IBaseStatsRank;
|
||||
}
|
||||
export type League = 'great' | 'ultra';
|
||||
export interface ILeaguePokemon extends IPokemon {
|
||||
pvp : {
|
||||
great : Array<IStats>;
|
||||
ultra : Array<IStats>;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IStats {
|
||||
cp : number;
|
||||
|
||||
@ -1,10 +1,6 @@
|
||||
import { League, MaxCpByLeague } from 'app/models/League';
|
||||
import { LevelMultipliers } from 'app/models/LevelMultipliers';
|
||||
import { IBaseStats, League } from 'app/models/Pokemon';
|
||||
|
||||
const leagueMaxCp = {
|
||||
great: 1500,
|
||||
ultra: 1500
|
||||
};
|
||||
import { IBaseStats } from 'app/models/Pokemon';
|
||||
|
||||
const calculateStatsFormula = (baseStats : IBaseStats, ivHp : number, ivAtk : number, ivDef : number) => Math.sqrt(baseStats.baseStamina + ivHp) * Math.sqrt(baseStats.baseDefense + ivDef) * (baseStats.baseAttack + ivAtk);
|
||||
|
||||
@ -22,7 +18,7 @@ export const calculateStatAtLevel = (level : number, baseStatValue : number, ivS
|
||||
};
|
||||
|
||||
export const calculateMaxLevelForLeague = (baseStats : IBaseStats, ivHp : number, ivAtk : number, ivDef : number, league : League) => {
|
||||
const maxCp = leagueMaxCp[league];
|
||||
const maxCp = MaxCpByLeague[league];
|
||||
const statsFormula = calculateStatsFormula(baseStats, ivHp, ivAtk, ivDef);
|
||||
let level = 1;
|
||||
for (let i = LevelMultipliers.length - 1; i >= 0; i--) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user