split iv stuff into component

This commit is contained in:
Jeff Colombo 2019-03-04 22:52:28 -05:00
parent 4bfb76bde8
commit 6de075e08c
8 changed files with 728 additions and 601 deletions

157
dist/app.css vendored
View File

@ -108,6 +108,70 @@
border-image-outset: 1; border-image-outset: 1;
padding: 2px; } padding: 2px; }
.PokemonExplorer__wrapper__3U9Pu {
margin: 0 auto;
width: 30rem;
display: flex;
flex-flow: column nowrap; }
.PokemonExplorer__container__3LR-_ {
display: flex;
justify-content: space-evenly; }
.PokemonExplorer__container__3LR-_ .PokemonExplorer__leftColumn__1qHS1,
.PokemonExplorer__container__3LR-_ .PokemonExplorer__rightColumn__KvY23 {
display: flex;
flex-flow: column nowrap;
flex-basis: 45%;
align-items: center; }
.PokemonExplorer__container__3LR-_ .PokemonExplorer__leftColumn__1qHS1 {
text-align: center; }
.PokemonExplorer__container__3LR-_ .PokemonExplorer__rightColumn__KvY23 {
flex-grow: 1;
align-items: start; }
.LeagueIvExplorer__container__3GKct {
margin-bottom: 1rem; }
.LeagueIvExplorer__leftColumn__3au0L { }
.LeagueIvExplorer__rightColumn__1eyvh { }
.LeagueIvExplorer__leaguePokemonRank__3bjyU {
justify-content: flex-start;
flex-wrap: wrap; }
.LeagueIvExplorer__leaguePokemonRank__3bjyU .LeagueIvExplorer__pokemonInfoWrapper__3WVsh {
flex: 1 0 100%;
display: flex; }
.LeagueIvExplorer__leaguePokemonRank__3bjyU .LeagueIvExplorer__leftColumn__3au0L {
align-items: flex-start; }
.LeagueIvExplorer__leaguePokemonRank__3bjyU .LeagueIvExplorer__pokemonRankValue__3k3ih {
display: inline; }
.LeagueIvExplorer__ivsContainer__31sfb {
flex: 0 999 auto;
display: flex;
flex-flow: column nowrap;
/* for Firefox */ }
.LeagueIvExplorer__ivsContainer__31sfb .title.LeagueIvExplorer__ivContainerTitle__3Z3eX {
display: flex;
justify-content: flex-end;
background-color: transparent;
padding: 0; }
.LeagueIvExplorer__ivsContainer__31sfb .title.LeagueIvExplorer__ivContainerTitle__3Z3eX > * {
background-color: #fff; }
.LeagueIvExplorer__ivsContainer__31sfb .title.LeagueIvExplorer__ivContainerTitle__3Z3eX > *:first-child {
margin-right: auto;
padding: 0 0.5em; }
.LeagueIvExplorer__ivsContainer__31sfb .title.LeagueIvExplorer__ivContainerTitle__3Z3eX > *:last-child {
padding-right: 0.5em; }
.LeagueIvExplorer__ivsContainer__31sfb.LeagueIvExplorer__diplayingIvList__1Q5r8 {
padding: 1.5rem 0 0; }
.LeagueIvExplorer__ivsContainer__31sfb.LeagueIvExplorer__diplayingIvList__1Q5r8 .title.LeagueIvExplorer__ivContainerTitle__3Z3eX {
margin-bottom: 0;
margin-right: -8px;
margin-left: -8px;
padding: 0 2.5rem; }
.TypeIndicator__pokemonType__3MOQI { .TypeIndicator__pokemonType__3MOQI {
text-transform: uppercase; } text-transform: uppercase; }
.TypeIndicator__pokemonType__3MOQI.nes-container { .TypeIndicator__pokemonType__3MOQI.nes-container {
@ -258,63 +322,6 @@
background-color: #000; background-color: #000;
opacity: 0.7; } opacity: 0.7; }
.PokemonExplorer__wrapper__3U9Pu {
margin: 0 auto;
width: 30rem;
display: flex;
flex-flow: column nowrap; }
.PokemonExplorer__container__3LR-_ {
display: flex;
justify-content: space-evenly; }
.PokemonExplorer__container__3LR-_ .PokemonExplorer__leftColumn__1qHS1,
.PokemonExplorer__container__3LR-_ .PokemonExplorer__rightColumn__KvY23 {
display: flex;
flex-flow: column nowrap;
flex-basis: 45%;
align-items: center; }
.PokemonExplorer__container__3LR-_ .PokemonExplorer__leftColumn__1qHS1 {
text-align: center; }
.PokemonExplorer__container__3LR-_ .PokemonExplorer__rightColumn__KvY23 {
flex-grow: 1;
align-items: start; }
.PokemonExplorer__leaguePokemonRank__2Oq1D {
justify-content: flex-start;
flex-wrap: wrap; }
.PokemonExplorer__leaguePokemonRank__2Oq1D .PokemonExplorer__pokemonInfoWrapper__1oqey {
flex: 1 0 100%;
display: flex; }
.PokemonExplorer__leaguePokemonRank__2Oq1D .PokemonExplorer__pokemonInfoLeftColumn__2k9b7 {
align-items: flex-start; }
.PokemonExplorer__leaguePokemonRank__2Oq1D .PokemonExplorer__pokemonRankValue__11Y0L {
display: inline; }
.PokemonExplorer__ivsContainer__Jh0Sr {
flex: 0 999 auto;
display: flex;
flex-flow: column nowrap;
/* for Firefox */ }
.PokemonExplorer__ivsContainer__Jh0Sr .title.PokemonExplorer__ivContainerTitle__3cq4P {
display: flex;
justify-content: flex-end;
background-color: transparent;
padding: 0; }
.PokemonExplorer__ivsContainer__Jh0Sr .title.PokemonExplorer__ivContainerTitle__3cq4P > * {
background-color: #fff; }
.PokemonExplorer__ivsContainer__Jh0Sr .title.PokemonExplorer__ivContainerTitle__3cq4P > *:first-child {
margin-right: auto;
padding: 0 0.5em; }
.PokemonExplorer__ivsContainer__Jh0Sr .title.PokemonExplorer__ivContainerTitle__3cq4P > *:last-child {
padding-right: 0.5em; }
.PokemonExplorer__ivsContainer__Jh0Sr.PokemonExplorer__diplayingIvList__3Ii7D {
padding: 1.5rem 0 0; }
.PokemonExplorer__ivsContainer__Jh0Sr.PokemonExplorer__diplayingIvList__3Ii7D .title.PokemonExplorer__ivContainerTitle__3cq4P {
margin-bottom: 0;
margin-right: -8px;
margin-left: -8px;
padding: 0 2.5rem; }
.PokemonDisplay__highlight__h50BA { .PokemonDisplay__highlight__h50BA {
color: #fff; color: #fff;
pointer-events: none; } pointer-events: none; }
@ -368,42 +375,6 @@
flex-grow: 1; flex-grow: 1;
align-items: start; } align-items: start; }
.PokemonExplorer__leaguePokemonRank__2Oq1D {
justify-content: flex-start;
flex-wrap: wrap; }
.PokemonExplorer__leaguePokemonRank__2Oq1D .PokemonExplorer__pokemonInfoWrapper__1oqey {
flex: 1 0 100%;
display: flex; }
.PokemonExplorer__leaguePokemonRank__2Oq1D .PokemonExplorer__pokemonInfoLeftColumn__2k9b7 {
align-items: flex-start; }
.PokemonExplorer__leaguePokemonRank__2Oq1D .PokemonExplorer__pokemonRankValue__11Y0L {
display: inline; }
.PokemonExplorer__ivsContainer__Jh0Sr {
flex: 0 999 auto;
display: flex;
flex-flow: column nowrap;
/* for Firefox */ }
.PokemonExplorer__ivsContainer__Jh0Sr .title.PokemonExplorer__ivContainerTitle__3cq4P {
display: flex;
justify-content: flex-end;
background-color: transparent;
padding: 0; }
.PokemonExplorer__ivsContainer__Jh0Sr .title.PokemonExplorer__ivContainerTitle__3cq4P > * {
background-color: #fff; }
.PokemonExplorer__ivsContainer__Jh0Sr .title.PokemonExplorer__ivContainerTitle__3cq4P > *:first-child {
margin-right: auto;
padding: 0 0.5em; }
.PokemonExplorer__ivsContainer__Jh0Sr .title.PokemonExplorer__ivContainerTitle__3cq4P > *:last-child {
padding-right: 0.5em; }
.PokemonExplorer__ivsContainer__Jh0Sr.PokemonExplorer__diplayingIvList__3Ii7D {
padding: 1.5rem 0 0; }
.PokemonExplorer__ivsContainer__Jh0Sr.PokemonExplorer__diplayingIvList__3Ii7D .title.PokemonExplorer__ivContainerTitle__3cq4P {
margin-bottom: 0;
margin-right: -8px;
margin-left: -8px;
padding: 0 2.5rem; }
.TypeEffectiveDisplay__multiplierWrapper__14os7 { .TypeEffectiveDisplay__multiplierWrapper__14os7 {
position: relative; position: relative;
padding-top: 6px; padding-top: 6px;

482
dist/main-bundle.js vendored
View File

@ -37519,6 +37519,276 @@ exports.IvForm = IvForm;
/***/ }), /***/ }),
/***/ "./src/ts/app/components/PokemonExplorer/LeagueIvExplorer.tsx":
/*!********************************************************************!*\
!*** ./src/ts/app/components/PokemonExplorer/LeagueIvExplorer.tsx ***!
\********************************************************************/
/*! no static exports found */
/*! ModuleConcatenation bailout: Module is not an ECMAScript module */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var __importDefault = this && this.__importDefault || function (mod) {
return mod && mod.__esModule ? mod : {
"default": mod
};
};
var __importStar = this && this.__importStar || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) {
if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
}
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", {
value: true
});
var react_1 = __importDefault(__webpack_require__(/*! react */ "./node_modules/react/index.js"));
var classnames_1 = __importDefault(__webpack_require__(/*! classnames */ "./node_modules/classnames/index.js"));
var League_1 = __webpack_require__(/*! app/models/League */ "./src/ts/app/models/League.ts");
var Pokemon_1 = __webpack_require__(/*! app/models/Pokemon */ "./src/ts/app/models/Pokemon.ts");
var calculator_1 = __webpack_require__(/*! app/utils/calculator */ "./src/ts/app/utils/calculator.ts");
var IvForm_1 = __webpack_require__(/*! ./IvForm */ "./src/ts/app/components/PokemonExplorer/IvForm.tsx");
var LeagueSelector_1 = __webpack_require__(/*! ./LeagueSelector */ "./src/ts/app/components/PokemonExplorer/LeagueSelector.tsx");
var LeagueStatsList_1 = __webpack_require__(/*! ./LeagueStatsList */ "./src/ts/app/components/PokemonExplorer/LeagueStatsList.tsx");
var StatDisplay_1 = __webpack_require__(/*! ./StatDisplay */ "./src/ts/app/components/PokemonExplorer/StatDisplay.tsx");
var styles = __importStar(__webpack_require__(/*! ./styles/LeagueIvExplorer.scss */ "./src/ts/app/components/PokemonExplorer/styles/LeagueIvExplorer.scss"));
var IvDisplayMode;
(function (IvDisplayMode) {
IvDisplayMode["MANUAL"] = "manual";
IvDisplayMode["LIST"] = "list";
})(IvDisplayMode || (IvDisplayMode = {}));
var LeagueIvExplorer =
/*#__PURE__*/
function (_react_1$default$Comp) {
_inherits(LeagueIvExplorer, _react_1$default$Comp);
function LeagueIvExplorer(props) {
var _this;
_classCallCheck(this, LeagueIvExplorer);
_this = _possibleConstructorReturn(this, _getPrototypeOf(LeagueIvExplorer).call(this, props));
_this.handleActivateLeagueStats = function (stats) {
var handleChangeIndividualValue = _this.props.handleChangeIndividualValue;
handleChangeIndividualValue('level', stats.level);
handleChangeIndividualValue('hp', stats.ivHp);
handleChangeIndividualValue('atk', stats.ivAtk);
handleChangeIndividualValue('def', stats.ivDef);
};
_this.handleIvDisplayModeManual = function () {
_this.setState({
ivDisplayMode: IvDisplayMode.MANUAL
});
};
_this.handleIvDisplayModeList = function () {
_this.setState({
ivDisplayMode: IvDisplayMode.LIST
});
};
_this.state = {
ivDisplayMode: IvDisplayMode.MANUAL
};
return _this;
}
_createClass(LeagueIvExplorer, [{
key: "render",
value: function render() {
var _this$props = this.props,
activeLeague = _this$props.activeLeague,
leaguePokemon = _this$props.leaguePokemon,
individualValues = _this$props.individualValues,
handleChangeIndividualValue = _this$props.handleChangeIndividualValue,
handleMaximizeLevel = _this$props.handleMaximizeLevel,
handleChangeLeague = _this$props.handleChangeLeague;
var ivDisplayMode = this.state.ivDisplayMode;
var rankedPokemon = null; // default to first pokemon (should be S tier)
if (individualValues.level === null && individualValues.ivHp === null && individualValues.ivAtk === null && individualValues.ivDef === null) {
rankedPokemon = leaguePokemon.pvp[activeLeague][0]; // a full spec'd pokemon has been entered
} else if (individualValues.level !== null && individualValues.ivHp !== null && individualValues.ivAtk !== null && individualValues.ivDef !== null) {
leaguePokemon.pvp[activeLeague].some(function (stats) {
if (individualValues.level === stats.level && individualValues.ivHp === stats.ivHp && individualValues.ivAtk === stats.ivAtk && individualValues.ivDef === stats.ivDef) {
rankedPokemon = stats;
return true;
}
return false;
}); // we don't have the data for this terrible mon
if (rankedPokemon === null) {
rankedPokemon = {
cp: calculator_1.calculateCp(leaguePokemon.stats, individualValues.level, individualValues.ivHp, individualValues.ivAtk, individualValues.ivDef),
level: individualValues.level,
ivHp: individualValues.ivHp,
ivAtk: individualValues.ivAtk,
ivDef: individualValues.ivDef,
hp: calculator_1.calculateStatAtLevel(individualValues.level, leaguePokemon.stats.baseStamina, individualValues.ivHp),
atk: calculator_1.calculateStatAtLevel(individualValues.level, leaguePokemon.stats.baseAttack, individualValues.ivAtk),
def: calculator_1.calculateStatAtLevel(individualValues.level, leaguePokemon.stats.baseDefense, individualValues.ivDef),
total: 0,
speciesGrade: Pokemon_1.Grade.F,
metaGrade: Pokemon_1.Grade.F
};
rankedPokemon.total = rankedPokemon.hp + rankedPokemon.atk + rankedPokemon.def;
}
}
var rankedGrade = rankedPokemon !== null ? Pokemon_1.Grade[rankedPokemon.speciesGrade] : '-';
var rankedCp = rankedPokemon !== null ? rankedPokemon.cp : '-';
var _LeagueIvExplorer$cal = LeagueIvExplorer.calculateStatRanks(rankedPokemon, leaguePokemon.statMax[activeLeague]),
rankedHp = _LeagueIvExplorer$cal.rankedHp,
rankedAtk = _LeagueIvExplorer$cal.rankedAtk,
rankedDef = _LeagueIvExplorer$cal.rankedDef,
staminaStatRank = _LeagueIvExplorer$cal.staminaStatRank,
attackStatRank = _LeagueIvExplorer$cal.attackStatRank,
defenseStatRank = _LeagueIvExplorer$cal.defenseStatRank;
var containerCss = classnames_1.default('nes-container', 'with-title');
var containerTitleCss = classnames_1.default('title');
var ivContainerTitleCss = classnames_1.default(containerTitleCss, styles.ivContainerTitle);
var formContainerCss = classnames_1.default(containerCss, styles.ivsContainer, 'form', _defineProperty({}, styles.diplayingIvList, ivDisplayMode === IvDisplayMode.LIST));
var leaugeRankCss = classnames_1.default(styles.container, styles.leaguePokemonRank, containerCss, {
'with-title': false
});
var leagueLeftColumnCss = classnames_1.default(styles.leftColumn);
var leagueRightColumnCss = classnames_1.default(styles.rightColumn);
var pokemonInfoWrapper = classnames_1.default(styles.container, styles.pokemonInfoWrapper);
return react_1.default.createElement(react_1.default.Fragment, null, react_1.default.createElement(LeagueSelector_1.LeagueSelector, {
activeLeague: activeLeague,
handleLeagueSelect: handleChangeLeague
}), react_1.default.createElement("section", {
className: formContainerCss
}, react_1.default.createElement("h5", {
className: ivContainerTitleCss
}, react_1.default.createElement("span", null, "IVs"), react_1.default.createElement("label", null, react_1.default.createElement("input", {
className: "nes-radio",
type: "radio",
value: "manual",
checked: ivDisplayMode === IvDisplayMode.MANUAL,
onChange: this.handleIvDisplayModeManual
}), " ", react_1.default.createElement("span", null, "Manual")), react_1.default.createElement("label", null, react_1.default.createElement("input", {
className: "nes-radio",
type: "radio",
value: "list",
checked: ivDisplayMode === IvDisplayMode.LIST,
onChange: this.handleIvDisplayModeList
}), " ", react_1.default.createElement("span", null, "List"))), ivDisplayMode === IvDisplayMode.MANUAL && react_1.default.createElement(IvForm_1.IvForm, {
ivs: individualValues,
placeholder: leaguePokemon.pvp[activeLeague][0],
handleChangeIndividualValue: handleChangeIndividualValue,
handleMaximizeLevel: handleMaximizeLevel
}), ivDisplayMode === IvDisplayMode.LIST && react_1.default.createElement(LeagueStatsList_1.LeagueStatsList, {
activePokemonId: leaguePokemon.id,
activePokemonForm: leaguePokemon.form,
activeIndividualValues: individualValues,
leagueStatsList: leaguePokemon.pvp[activeLeague],
handleActivateLeagueStats: this.handleActivateLeagueStats
})), react_1.default.createElement("section", {
className: leaugeRankCss
}, react_1.default.createElement("h5", {
className: containerTitleCss
}, "Rank"), react_1.default.createElement("div", {
className: pokemonInfoWrapper
}, react_1.default.createElement("div", {
className: leagueLeftColumnCss
}, rankedPokemon === null || rankedPokemon.cp > League_1.MaxCpByLeague[activeLeague] && react_1.default.createElement("div", null, react_1.default.createElement("h1", {
className: styles.pokemonRankValue
}, "N/A")), rankedPokemon !== null && rankedPokemon.cp <= League_1.MaxCpByLeague[activeLeague] && react_1.default.createElement("div", null, react_1.default.createElement("h1", {
className: styles.pokemonRankValue
}, rankedGrade), " Rank"), react_1.default.createElement("div", null, "CP ", react_1.default.createElement("h1", {
className: styles.pokemonRankValue
}, rankedCp))), react_1.default.createElement("div", {
className: leagueRightColumnCss
}, react_1.default.createElement(StatDisplay_1.StatDisplay, {
statLabel: "HP".concat(String.fromCharCode(160)),
statValue: rankedHp,
statRank: staminaStatRank
}), react_1.default.createElement(StatDisplay_1.StatDisplay, {
statLabel: "ATK",
statValue: rankedAtk,
statRank: attackStatRank
}), react_1.default.createElement(StatDisplay_1.StatDisplay, {
statLabel: "DEF",
statValue: rankedDef,
statRank: defenseStatRank
})))));
}
}], [{
key: "calculateStatRanks",
value: function calculateStatRanks(rankedPokemon, stats) {
var rankedHp = rankedPokemon !== null ? rankedPokemon.hp : 0;
var rankedAtk = rankedPokemon !== null ? rankedPokemon.atk : 0;
var rankedDef = rankedPokemon !== null ? rankedPokemon.def : 0;
var maxStamina = stats.stamina;
var staminaStatRank = Math.floor((rankedHp - maxStamina.worst) / (maxStamina.best - maxStamina.worst) * 100);
var maxAttack = stats.attack;
var attackStatRank = Math.floor((rankedAtk - maxAttack.worst) / (maxAttack.best - maxAttack.worst) * 100);
var maxDefense = stats.defense;
var defenseStatRank = Math.floor((rankedDef - maxDefense.worst) / (maxDefense.best - maxDefense.worst) * 100);
return {
rankedHp: rankedHp,
rankedAtk: rankedAtk,
rankedDef: rankedDef,
staminaStatRank: staminaStatRank,
attackStatRank: attackStatRank,
defenseStatRank: defenseStatRank
};
}
}]);
return LeagueIvExplorer;
}(react_1.default.Component);
exports.LeagueIvExplorer = LeagueIvExplorer;
/***/ }),
/***/ "./src/ts/app/components/PokemonExplorer/LeagueSelector.tsx": /***/ "./src/ts/app/components/PokemonExplorer/LeagueSelector.tsx":
/*!******************************************************************!*\ /*!******************************************************************!*\
!*** ./src/ts/app/components/PokemonExplorer/LeagueSelector.tsx ***! !*** ./src/ts/app/components/PokemonExplorer/LeagueSelector.tsx ***!
@ -38076,8 +38346,6 @@ exports.PokemonDisplay = PokemonDisplay;
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
@ -38118,71 +38386,21 @@ var react_1 = __importDefault(__webpack_require__(/*! react */ "./node_modules/r
var classnames_1 = __importDefault(__webpack_require__(/*! classnames */ "./node_modules/classnames/index.js")); var classnames_1 = __importDefault(__webpack_require__(/*! classnames */ "./node_modules/classnames/index.js"));
var League_1 = __webpack_require__(/*! app/models/League */ "./src/ts/app/models/League.ts"); var LeagueIvExplorer_1 = __webpack_require__(/*! ./LeagueIvExplorer */ "./src/ts/app/components/PokemonExplorer/LeagueIvExplorer.tsx");
var Pokemon_1 = __webpack_require__(/*! app/models/Pokemon */ "./src/ts/app/models/Pokemon.ts");
var calculator_1 = __webpack_require__(/*! app/utils/calculator */ "./src/ts/app/utils/calculator.ts");
var IvForm_1 = __webpack_require__(/*! ./IvForm */ "./src/ts/app/components/PokemonExplorer/IvForm.tsx");
var LeagueSelector_1 = __webpack_require__(/*! ./LeagueSelector */ "./src/ts/app/components/PokemonExplorer/LeagueSelector.tsx");
var LeagueStatsList_1 = __webpack_require__(/*! ./LeagueStatsList */ "./src/ts/app/components/PokemonExplorer/LeagueStatsList.tsx");
var PokemonDisplay_1 = __webpack_require__(/*! ./PokemonDisplay */ "./src/ts/app/components/PokemonExplorer/PokemonDisplay.tsx"); var PokemonDisplay_1 = __webpack_require__(/*! ./PokemonDisplay */ "./src/ts/app/components/PokemonExplorer/PokemonDisplay.tsx");
var StatDisplay_1 = __webpack_require__(/*! ./StatDisplay */ "./src/ts/app/components/PokemonExplorer/StatDisplay.tsx");
var styles = __importStar(__webpack_require__(/*! ./styles/PokemonExplorer.scss */ "./src/ts/app/components/PokemonExplorer/styles/PokemonExplorer.scss")); var styles = __importStar(__webpack_require__(/*! ./styles/PokemonExplorer.scss */ "./src/ts/app/components/PokemonExplorer/styles/PokemonExplorer.scss"));
var IvDisplayMode;
(function (IvDisplayMode) {
IvDisplayMode["MANUAL"] = "manual";
IvDisplayMode["LIST"] = "list";
})(IvDisplayMode || (IvDisplayMode = {}));
var PokemonExplorer = var PokemonExplorer =
/*#__PURE__*/ /*#__PURE__*/
function (_react_1$default$Comp) { function (_react_1$default$Comp) {
_inherits(PokemonExplorer, _react_1$default$Comp); _inherits(PokemonExplorer, _react_1$default$Comp);
function PokemonExplorer(props) { function PokemonExplorer() {
var _this;
_classCallCheck(this, PokemonExplorer); _classCallCheck(this, PokemonExplorer);
_this = _possibleConstructorReturn(this, _getPrototypeOf(PokemonExplorer).call(this, props)); return _possibleConstructorReturn(this, _getPrototypeOf(PokemonExplorer).apply(this, arguments));
_this.handleActivateLeagueStats = function (stats) {
var handleChangeIndividualValue = _this.props.handleChangeIndividualValue;
handleChangeIndividualValue('level', stats.level);
handleChangeIndividualValue('hp', stats.ivHp);
handleChangeIndividualValue('atk', stats.ivAtk);
handleChangeIndividualValue('def', stats.ivDef);
};
_this.handleLeagueSelect = function (league) {
_this.props.handleChangeLeague(league);
};
_this.handleIvDisplayModeManual = function () {
_this.setState({
ivDisplayMode: IvDisplayMode.MANUAL
});
};
_this.handleIvDisplayModeList = function () {
_this.setState({
ivDisplayMode: IvDisplayMode.LIST
});
};
_this.state = {
ivDisplayMode: IvDisplayMode.MANUAL
};
return _this;
} }
_createClass(PokemonExplorer, [{ _createClass(PokemonExplorer, [{
@ -38194,148 +38412,23 @@ function (_react_1$default$Comp) {
activeLeague = _this$props.activeLeague, activeLeague = _this$props.activeLeague,
individualValues = _this$props.individualValues, individualValues = _this$props.individualValues,
leaguePokemon = _this$props.leaguePokemon, leaguePokemon = _this$props.leaguePokemon,
handleChangeLeague = _this$props.handleChangeLeague,
handleChangeIndividualValue = _this$props.handleChangeIndividualValue, handleChangeIndividualValue = _this$props.handleChangeIndividualValue,
handleMaximizeLevel = _this$props.handleMaximizeLevel; handleMaximizeLevel = _this$props.handleMaximizeLevel;
var ivDisplayMode = this.state.ivDisplayMode;
var rankedPokemon = null; // default to first pokemon (should be S tier)
if (individualValues.level === null && individualValues.ivHp === null && individualValues.ivAtk === null && individualValues.ivDef === null) {
rankedPokemon = leaguePokemon.pvp[activeLeague][0]; // a full spec'd pokemon has been entered
} else if (individualValues.level !== null && individualValues.ivHp !== null && individualValues.ivAtk !== null && individualValues.ivDef !== null) {
leaguePokemon.pvp[activeLeague].some(function (stats) {
if (individualValues.level === stats.level && individualValues.ivHp === stats.ivHp && individualValues.ivAtk === stats.ivAtk && individualValues.ivDef === stats.ivDef) {
rankedPokemon = stats;
return true;
}
return false;
}); // we don't have the data for this terrible mon
if (rankedPokemon === null) {
rankedPokemon = {
cp: calculator_1.calculateCp(leaguePokemon.stats, individualValues.level, individualValues.ivHp, individualValues.ivAtk, individualValues.ivDef),
level: individualValues.level,
ivHp: individualValues.ivHp,
ivAtk: individualValues.ivAtk,
ivDef: individualValues.ivDef,
hp: calculator_1.calculateStatAtLevel(individualValues.level, leaguePokemon.stats.baseStamina, individualValues.ivHp),
atk: calculator_1.calculateStatAtLevel(individualValues.level, leaguePokemon.stats.baseAttack, individualValues.ivAtk),
def: calculator_1.calculateStatAtLevel(individualValues.level, leaguePokemon.stats.baseDefense, individualValues.ivDef),
total: 0,
speciesGrade: Pokemon_1.Grade.F,
metaGrade: Pokemon_1.Grade.F
};
rankedPokemon.total = rankedPokemon.hp + rankedPokemon.atk + rankedPokemon.def;
}
}
var rankedGrade = rankedPokemon !== null ? Pokemon_1.Grade[rankedPokemon.speciesGrade] : '-';
var rankedCp = rankedPokemon !== null ? rankedPokemon.cp : '-';
var _PokemonExplorer$calc = PokemonExplorer.calculateStatRanks(rankedPokemon, leaguePokemon.statMax[activeLeague]),
rankedHp = _PokemonExplorer$calc.rankedHp,
rankedAtk = _PokemonExplorer$calc.rankedAtk,
rankedDef = _PokemonExplorer$calc.rankedDef,
staminaStatRank = _PokemonExplorer$calc.staminaStatRank,
attackStatRank = _PokemonExplorer$calc.attackStatRank,
defenseStatRank = _PokemonExplorer$calc.defenseStatRank;
var wrapperCss = classnames_1.default(styles.wrapper, className); var wrapperCss = classnames_1.default(styles.wrapper, className);
var containerCss = classnames_1.default('nes-container', 'with-title');
var containerTitleCss = classnames_1.default('title');
var ivContainerTitleCss = classnames_1.default(containerTitleCss, styles.ivContainerTitle);
var formContainerCss = classnames_1.default(containerCss, styles.ivsContainer, 'form', _defineProperty({}, styles.diplayingIvList, ivDisplayMode === IvDisplayMode.LIST));
var leaugeRankCss = classnames_1.default(styles.container, styles.leaguePokemonRank, containerCss, {
'with-title': false
});
var leagueLeftColumnCss = classnames_1.default(styles.leftColumn, styles.pokemonInfoLeftColumn);
var leagueRightColumnCss = classnames_1.default(styles.rightColumn);
var pokemonInfoWrapper = classnames_1.default(styles.container, styles.pokemonInfoWrapper);
return react_1.default.createElement(react_1.default.Fragment, null, react_1.default.createElement("div", { return react_1.default.createElement(react_1.default.Fragment, null, react_1.default.createElement("div", {
className: wrapperCss className: wrapperCss
}, react_1.default.createElement(PokemonDisplay_1.PokemonDisplay, { }, react_1.default.createElement(PokemonDisplay_1.PokemonDisplay, {
leaguePokemon: leaguePokemon, leaguePokemon: leaguePokemon,
temporaryNavigationIsActive: temporaryNavigationIsActive temporaryNavigationIsActive: temporaryNavigationIsActive
}), react_1.default.createElement(LeagueSelector_1.LeagueSelector, { }), react_1.default.createElement(LeagueIvExplorer_1.LeagueIvExplorer, {
activeLeague: activeLeague, activeLeague: activeLeague,
handleLeagueSelect: this.handleLeagueSelect leaguePokemon: leaguePokemon,
}), react_1.default.createElement("section", { individualValues: individualValues,
className: formContainerCss
}, react_1.default.createElement("h5", {
className: ivContainerTitleCss
}, react_1.default.createElement("span", null, "IVs"), react_1.default.createElement("label", null, react_1.default.createElement("input", {
className: "nes-radio",
type: "radio",
value: "manual",
checked: ivDisplayMode === IvDisplayMode.MANUAL,
onChange: this.handleIvDisplayModeManual
}), " ", react_1.default.createElement("span", null, "Manual")), react_1.default.createElement("label", null, react_1.default.createElement("input", {
className: "nes-radio",
type: "radio",
value: "list",
checked: ivDisplayMode === IvDisplayMode.LIST,
onChange: this.handleIvDisplayModeList
}), " ", react_1.default.createElement("span", null, "List"))), ivDisplayMode === IvDisplayMode.MANUAL && react_1.default.createElement(IvForm_1.IvForm, {
ivs: individualValues,
placeholder: leaguePokemon.pvp[activeLeague][0],
handleChangeIndividualValue: handleChangeIndividualValue, handleChangeIndividualValue: handleChangeIndividualValue,
handleMaximizeLevel: handleMaximizeLevel handleMaximizeLevel: handleMaximizeLevel,
}), ivDisplayMode === IvDisplayMode.LIST && react_1.default.createElement(LeagueStatsList_1.LeagueStatsList, { handleChangeLeague: handleChangeLeague
activePokemonId: leaguePokemon.id, })));
activePokemonForm: leaguePokemon.form,
activeIndividualValues: individualValues,
leagueStatsList: leaguePokemon.pvp[activeLeague],
handleActivateLeagueStats: this.handleActivateLeagueStats
})), react_1.default.createElement("section", {
className: leaugeRankCss
}, react_1.default.createElement("h5", {
className: containerTitleCss
}, "Rank"), react_1.default.createElement("div", {
className: pokemonInfoWrapper
}, react_1.default.createElement("div", {
className: leagueLeftColumnCss
}, rankedPokemon === null || rankedPokemon.cp > League_1.MaxCpByLeague[activeLeague] && react_1.default.createElement("div", null, react_1.default.createElement("h1", {
className: styles.pokemonRankValue
}, "N/A")), rankedPokemon !== null && rankedPokemon.cp <= League_1.MaxCpByLeague[activeLeague] && react_1.default.createElement("div", null, react_1.default.createElement("h1", {
className: styles.pokemonRankValue
}, rankedGrade), " Rank"), react_1.default.createElement("div", null, "CP ", react_1.default.createElement("h1", {
className: styles.pokemonRankValue
}, rankedCp))), react_1.default.createElement("div", {
className: leagueRightColumnCss
}, react_1.default.createElement(StatDisplay_1.StatDisplay, {
statLabel: "HP".concat(String.fromCharCode(160)),
statValue: rankedHp,
statRank: staminaStatRank
}), react_1.default.createElement(StatDisplay_1.StatDisplay, {
statLabel: "ATK",
statValue: rankedAtk,
statRank: attackStatRank
}), react_1.default.createElement(StatDisplay_1.StatDisplay, {
statLabel: "DEF",
statValue: rankedDef,
statRank: defenseStatRank
}))))));
}
}], [{
key: "calculateStatRanks",
value: function calculateStatRanks(rankedPokemon, stats) {
var rankedHp = rankedPokemon !== null ? rankedPokemon.hp : 0;
var rankedAtk = rankedPokemon !== null ? rankedPokemon.atk : 0;
var rankedDef = rankedPokemon !== null ? rankedPokemon.def : 0;
var maxStamina = stats.stamina;
var staminaStatRank = Math.floor((rankedHp - maxStamina.worst) / (maxStamina.best - maxStamina.worst) * 100);
var maxAttack = stats.attack;
var attackStatRank = Math.floor((rankedAtk - maxAttack.worst) / (maxAttack.best - maxAttack.worst) * 100);
var maxDefense = stats.defense;
var defenseStatRank = Math.floor((rankedDef - maxDefense.worst) / (maxDefense.best - maxDefense.worst) * 100);
return {
rankedHp: rankedHp,
rankedAtk: rankedAtk,
rankedDef: rankedDef,
staminaStatRank: staminaStatRank,
attackStatRank: attackStatRank,
defenseStatRank: defenseStatRank
};
} }
}]); }]);
@ -39032,6 +39125,19 @@ module.exports = {"ivInput":"IvForm__ivInput__xR5IU","levelInput":"IvForm__level
/***/ }), /***/ }),
/***/ "./src/ts/app/components/PokemonExplorer/styles/LeagueIvExplorer.scss":
/*!****************************************************************************!*\
!*** ./src/ts/app/components/PokemonExplorer/styles/LeagueIvExplorer.scss ***!
\****************************************************************************/
/*! no static exports found */
/*! ModuleConcatenation bailout: Module is not an ECMAScript module */
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
module.exports = {"container":"LeagueIvExplorer__container__3GKct PokemonExplorer__container__3LR-_","leftColumn":"LeagueIvExplorer__leftColumn__3au0L PokemonExplorer__leftColumn__1qHS1","rightColumn":"LeagueIvExplorer__rightColumn__1eyvh PokemonExplorer__rightColumn__KvY23","leaguePokemonRank":"LeagueIvExplorer__leaguePokemonRank__3bjyU","pokemonInfoWrapper":"LeagueIvExplorer__pokemonInfoWrapper__3WVsh","pokemonRankValue":"LeagueIvExplorer__pokemonRankValue__3k3ih","ivsContainer":"LeagueIvExplorer__ivsContainer__31sfb","ivContainerTitle":"LeagueIvExplorer__ivContainerTitle__3Z3eX","diplayingIvList":"LeagueIvExplorer__diplayingIvList__1Q5r8"};
/***/ }),
/***/ "./src/ts/app/components/PokemonExplorer/styles/LeagueSelector.scss": /***/ "./src/ts/app/components/PokemonExplorer/styles/LeagueSelector.scss":
/*!**************************************************************************!*\ /*!**************************************************************************!*\
!*** ./src/ts/app/components/PokemonExplorer/styles/LeagueSelector.scss ***! !*** ./src/ts/app/components/PokemonExplorer/styles/LeagueSelector.scss ***!
@ -39080,7 +39186,7 @@ module.exports = {"highlight":"PokemonDisplay__highlight__h50BA PokemonApp__high
/***/ (function(module, exports, __webpack_require__) { /***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin // extracted by mini-css-extract-plugin
module.exports = {"wrapper":"PokemonExplorer__wrapper__3U9Pu","container":"PokemonExplorer__container__3LR-_","leftColumn":"PokemonExplorer__leftColumn__1qHS1","rightColumn":"PokemonExplorer__rightColumn__KvY23","leaguePokemonRank":"PokemonExplorer__leaguePokemonRank__2Oq1D","pokemonInfoWrapper":"PokemonExplorer__pokemonInfoWrapper__1oqey","pokemonInfoLeftColumn":"PokemonExplorer__pokemonInfoLeftColumn__2k9b7","pokemonRankValue":"PokemonExplorer__pokemonRankValue__11Y0L","ivsContainer":"PokemonExplorer__ivsContainer__Jh0Sr","ivContainerTitle":"PokemonExplorer__ivContainerTitle__3cq4P","diplayingIvList":"PokemonExplorer__diplayingIvList__3Ii7D"}; module.exports = {"wrapper":"PokemonExplorer__wrapper__3U9Pu","container":"PokemonExplorer__container__3LR-_","leftColumn":"PokemonExplorer__leftColumn__1qHS1","rightColumn":"PokemonExplorer__rightColumn__KvY23"};
/***/ }), /***/ }),

View File

@ -0,0 +1,275 @@
import React from 'react';
import classNames from 'classnames';
import { IBestWorstStats, ILeaguePokemon, League, MaxCpByLeague } from 'app/models/League';
import { Grade, IStats } from 'app/models/Pokemon';
import { calculateCp, calculateStatAtLevel } from 'app/utils/calculator';
import { IIndividualValues, IndividualValueKey } from './types';
import { IvForm } from './IvForm';
import { LeagueSelector } from './LeagueSelector';
import { LeagueStatsList } from './LeagueStatsList';
import { StatDisplay } from './StatDisplay';
import * as styles from './styles/LeagueIvExplorer.scss';
export interface ILeagueIvExplorerProps {
activeLeague : League;
leaguePokemon : ILeaguePokemon;
individualValues : IIndividualValues;
handleChangeIndividualValue : (stat : IndividualValueKey, value : number | null) => void;
handleMaximizeLevel : () => void;
handleChangeLeague : (league : League) => void;
}
enum IvDisplayMode {
MANUAL = 'manual',
LIST = 'list',
}
interface IState {
ivDisplayMode : IvDisplayMode;
}
export class LeagueIvExplorer extends React.Component<ILeagueIvExplorerProps, IState> {
private static calculateStatRanks(rankedPokemon : IStats | null, stats : IBestWorstStats) {
const rankedHp = rankedPokemon !== null ? rankedPokemon.hp : 0;
const rankedAtk = rankedPokemon !== null ? rankedPokemon.atk : 0;
const rankedDef = rankedPokemon !== null ? rankedPokemon.def : 0;
const maxStamina = stats.stamina;
const staminaStatRank = Math.floor(((rankedHp - maxStamina.worst) / (maxStamina.best - maxStamina.worst)) * 100);
const maxAttack = stats.attack;
const attackStatRank = Math.floor(((rankedAtk - maxAttack.worst) / (maxAttack.best - maxAttack.worst)) * 100);
const maxDefense = stats.defense;
const defenseStatRank = Math.floor(((rankedDef - maxDefense.worst) / (maxDefense.best - maxDefense.worst)) * 100);
return {
rankedHp,
rankedAtk,
rankedDef,
staminaStatRank,
attackStatRank,
defenseStatRank,
};
}
constructor(props : ILeagueIvExplorerProps) {
super(props);
this.state = {
ivDisplayMode: IvDisplayMode.MANUAL,
};
}
public render() {
const {
activeLeague,
leaguePokemon,
individualValues,
handleChangeIndividualValue,
handleMaximizeLevel,
handleChangeLeague,
} = this.props;
const {
ivDisplayMode,
} = this.state;
let rankedPokemon : IStats | null = null;
// default to first pokemon (should be S tier)
if (individualValues.level === null &&
individualValues.ivHp === null &&
individualValues.ivAtk === null &&
individualValues.ivDef === null
) {
rankedPokemon = leaguePokemon.pvp[activeLeague][0];
// a full spec'd pokemon has been entered
} else if (individualValues.level !== null &&
individualValues.ivHp !== null &&
individualValues.ivAtk !== null &&
individualValues.ivDef !== null
) {
leaguePokemon.pvp[activeLeague].some((stats) => {
if (individualValues.level === stats.level &&
individualValues.ivHp === stats.ivHp &&
individualValues.ivAtk === stats.ivAtk &&
individualValues.ivDef === stats.ivDef
) {
rankedPokemon = stats;
return true;
}
return false;
});
// we don't have the data for this terrible mon
if (rankedPokemon === null) {
rankedPokemon = {
cp: calculateCp(leaguePokemon.stats, individualValues.level, individualValues.ivHp, individualValues.ivAtk, individualValues.ivDef),
level: individualValues.level,
ivHp: individualValues.ivHp,
ivAtk: individualValues.ivAtk,
ivDef: individualValues.ivDef,
hp: calculateStatAtLevel(individualValues.level, leaguePokemon.stats.baseStamina, individualValues.ivHp),
atk: calculateStatAtLevel(individualValues.level, leaguePokemon.stats.baseAttack, individualValues.ivAtk),
def: calculateStatAtLevel(individualValues.level, leaguePokemon.stats.baseDefense, individualValues.ivDef),
total: 0,
speciesGrade: Grade.F,
metaGrade: Grade.F,
};
rankedPokemon.total = rankedPokemon.hp + rankedPokemon.atk + rankedPokemon.def;
}
}
const rankedGrade = rankedPokemon !== null ? Grade[rankedPokemon.speciesGrade] : '-';
const rankedCp = rankedPokemon !== null ? rankedPokemon.cp : '-';
const {
rankedHp,
rankedAtk,
rankedDef,
staminaStatRank,
attackStatRank,
defenseStatRank,
} = LeagueIvExplorer.calculateStatRanks(rankedPokemon, leaguePokemon.statMax[activeLeague]);
const containerCss = classNames(
'nes-container',
'with-title',
);
const containerTitleCss = classNames(
'title',
);
const ivContainerTitleCss = classNames(
containerTitleCss,
styles.ivContainerTitle
);
const formContainerCss = classNames(
containerCss,
styles.ivsContainer,
'form',
{
[styles.diplayingIvList]: ivDisplayMode === IvDisplayMode.LIST,
}
);
const leaugeRankCss = classNames(
styles.container,
styles.leaguePokemonRank,
containerCss,
{
'with-title': false
},
);
const leagueLeftColumnCss = classNames(
styles.leftColumn,
);
const leagueRightColumnCss = classNames(
styles.rightColumn,
);
const pokemonInfoWrapper = classNames(
styles.container,
styles.pokemonInfoWrapper
);
return (
<React.Fragment>
<LeagueSelector
activeLeague={ activeLeague }
handleLeagueSelect={ handleChangeLeague }
/>
<section className={ formContainerCss }>
<h5 className={ ivContainerTitleCss }>
<span>IVs</span>
<label>
<input
className="nes-radio"
type="radio"
value="manual"
checked={ ivDisplayMode === IvDisplayMode.MANUAL }
onChange={ this.handleIvDisplayModeManual }
/> <span>Manual</span>
</label>
<label>
<input
className="nes-radio"
type="radio"
value="list"
checked={ ivDisplayMode === IvDisplayMode.LIST }
onChange={ this.handleIvDisplayModeList }
/> <span>List</span>
</label>
</h5>
{ ivDisplayMode === IvDisplayMode.MANUAL &&
<IvForm
ivs={ individualValues }
placeholder={ leaguePokemon.pvp[activeLeague][0] }
handleChangeIndividualValue={ handleChangeIndividualValue }
handleMaximizeLevel={ handleMaximizeLevel }
/>
}
{ ivDisplayMode === IvDisplayMode.LIST &&
<LeagueStatsList
activePokemonId={ leaguePokemon.id }
activePokemonForm={ leaguePokemon.form }
activeIndividualValues={ individualValues }
leagueStatsList={ leaguePokemon.pvp[activeLeague] }
handleActivateLeagueStats={ this.handleActivateLeagueStats }
/>
}
</section>
<section className={ leaugeRankCss }>
<h5 className={ containerTitleCss }>Rank</h5>
<div className={ pokemonInfoWrapper }>
<div className={ leagueLeftColumnCss }>
{ rankedPokemon === null || rankedPokemon.cp > MaxCpByLeague[activeLeague] &&
<div><h1 className={ styles.pokemonRankValue }>N/A</h1></div>
}
{ rankedPokemon !== null && rankedPokemon.cp <= MaxCpByLeague[activeLeague] &&
<div><h1 className={ styles.pokemonRankValue }>{ rankedGrade }</h1> Rank</div>
}
<div>CP <h1 className={ styles.pokemonRankValue }>{ rankedCp }</h1></div>
</div>
<div className={ leagueRightColumnCss }>
<StatDisplay
statLabel={ `HP${ String.fromCharCode(160) }` }
statValue={ rankedHp }
statRank={ staminaStatRank }
/>
<StatDisplay
statLabel="ATK"
statValue={ rankedAtk }
statRank={ attackStatRank }
/>
<StatDisplay
statLabel="DEF"
statValue={ rankedDef }
statRank={ defenseStatRank }
/>
</div>
</div>
</section>
</React.Fragment>
);
}
private readonly handleActivateLeagueStats = (stats : IStats) => {
const { handleChangeIndividualValue } = this.props;
handleChangeIndividualValue('level', stats.level);
handleChangeIndividualValue('hp', stats.ivHp);
handleChangeIndividualValue('atk', stats.ivAtk);
handleChangeIndividualValue('def', stats.ivDef);
}
private readonly handleIvDisplayModeManual = () => {
this.setState({ ivDisplayMode: IvDisplayMode.MANUAL });
}
private readonly handleIvDisplayModeList = () => {
this.setState({ ivDisplayMode: IvDisplayMode.LIST });
}
}

View File

@ -2,72 +2,18 @@ import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { IBestWorstStats, ILeaguePokemon, League, MaxCpByLeague } from 'app/models/League'; import { ILeagueIvExplorerProps, LeagueIvExplorer } from './LeagueIvExplorer';
import { Grade, IStats } from 'app/models/Pokemon';
import { calculateCp, calculateStatAtLevel } from 'app/utils/calculator';
import { IIndividualValues, IndividualValueKey } from './types';
import { IvForm } from './IvForm';
import { LeagueSelector } from './LeagueSelector';
import { LeagueStatsList } from './LeagueStatsList';
import { PokemonDisplay } from './PokemonDisplay'; import { PokemonDisplay } from './PokemonDisplay';
import { StatDisplay } from './StatDisplay';
import * as styles from './styles/PokemonExplorer.scss'; import * as styles from './styles/PokemonExplorer.scss';
export interface IPokemonExplorerProps { export interface IPokemonExplorerProps extends ILeagueIvExplorerProps {
temporaryNavigationIsActive : boolean; temporaryNavigationIsActive : boolean;
className? : string; className? : string;
isLoading : boolean; isLoading : boolean;
activeLeague : League;
leaguePokemon : ILeaguePokemon;
individualValues : IIndividualValues;
handleChangeIndividualValue : (stat : IndividualValueKey, value : number | null) => void;
handleMaximizeLevel : () => void;
handleChangeLeague : (league : League) => void;
} }
enum IvDisplayMode { export class PokemonExplorer extends React.Component<IPokemonExplorerProps> {
MANUAL = 'manual',
LIST = 'list',
}
interface IState {
ivDisplayMode : IvDisplayMode;
}
export class PokemonExplorer extends React.Component<IPokemonExplorerProps, IState> {
private static calculateStatRanks(rankedPokemon : IStats | null, stats : IBestWorstStats) {
const rankedHp = rankedPokemon !== null ? rankedPokemon.hp : 0;
const rankedAtk = rankedPokemon !== null ? rankedPokemon.atk : 0;
const rankedDef = rankedPokemon !== null ? rankedPokemon.def : 0;
const maxStamina = stats.stamina;
const staminaStatRank = Math.floor(((rankedHp - maxStamina.worst) / (maxStamina.best - maxStamina.worst)) * 100);
const maxAttack = stats.attack;
const attackStatRank = Math.floor(((rankedAtk - maxAttack.worst) / (maxAttack.best - maxAttack.worst)) * 100);
const maxDefense = stats.defense;
const defenseStatRank = Math.floor(((rankedDef - maxDefense.worst) / (maxDefense.best - maxDefense.worst)) * 100);
return {
rankedHp,
rankedAtk,
rankedDef,
staminaStatRank,
attackStatRank,
defenseStatRank,
};
}
constructor(props : IPokemonExplorerProps) {
super(props);
this.state = {
ivDisplayMode: IvDisplayMode.MANUAL,
};
}
public render() { public render() {
const { const {
@ -76,117 +22,16 @@ export class PokemonExplorer extends React.Component<IPokemonExplorerProps, ISta
activeLeague, activeLeague,
individualValues, individualValues,
leaguePokemon, leaguePokemon,
handleChangeLeague,
handleChangeIndividualValue, handleChangeIndividualValue,
handleMaximizeLevel, handleMaximizeLevel,
} = this.props; } = this.props;
const {
ivDisplayMode,
} = this.state;
let rankedPokemon : IStats | null = null;
// default to first pokemon (should be S tier)
if (individualValues.level === null &&
individualValues.ivHp === null &&
individualValues.ivAtk === null &&
individualValues.ivDef === null
) {
rankedPokemon = leaguePokemon.pvp[activeLeague][0];
// a full spec'd pokemon has been entered
} else if (individualValues.level !== null &&
individualValues.ivHp !== null &&
individualValues.ivAtk !== null &&
individualValues.ivDef !== null
) {
leaguePokemon.pvp[activeLeague].some((stats) => {
if (individualValues.level === stats.level &&
individualValues.ivHp === stats.ivHp &&
individualValues.ivAtk === stats.ivAtk &&
individualValues.ivDef === stats.ivDef
) {
rankedPokemon = stats;
return true;
}
return false;
});
// we don't have the data for this terrible mon
if (rankedPokemon === null) {
rankedPokemon = {
cp: calculateCp(leaguePokemon.stats, individualValues.level, individualValues.ivHp, individualValues.ivAtk, individualValues.ivDef),
level: individualValues.level,
ivHp: individualValues.ivHp,
ivAtk: individualValues.ivAtk,
ivDef: individualValues.ivDef,
hp: calculateStatAtLevel(individualValues.level, leaguePokemon.stats.baseStamina, individualValues.ivHp),
atk: calculateStatAtLevel(individualValues.level, leaguePokemon.stats.baseAttack, individualValues.ivAtk),
def: calculateStatAtLevel(individualValues.level, leaguePokemon.stats.baseDefense, individualValues.ivDef),
total: 0,
speciesGrade: Grade.F,
metaGrade: Grade.F,
};
rankedPokemon.total = rankedPokemon.hp + rankedPokemon.atk + rankedPokemon.def;
}
}
const rankedGrade = rankedPokemon !== null ? Grade[rankedPokemon.speciesGrade] : '-';
const rankedCp = rankedPokemon !== null ? rankedPokemon.cp : '-';
const {
rankedHp,
rankedAtk,
rankedDef,
staminaStatRank,
attackStatRank,
defenseStatRank,
} = PokemonExplorer.calculateStatRanks(rankedPokemon, leaguePokemon.statMax[activeLeague]);
const wrapperCss = classNames( const wrapperCss = classNames(
styles.wrapper, styles.wrapper,
className className
); );
const containerCss = classNames(
'nes-container',
'with-title',
);
const containerTitleCss = classNames(
'title',
);
const ivContainerTitleCss = classNames(
containerTitleCss,
styles.ivContainerTitle
);
const formContainerCss = classNames(
containerCss,
styles.ivsContainer,
'form',
{
[styles.diplayingIvList]: ivDisplayMode === IvDisplayMode.LIST,
}
);
const leaugeRankCss = classNames(
styles.container,
styles.leaguePokemonRank,
containerCss,
{
'with-title': false
},
);
const leagueLeftColumnCss = classNames(
styles.leftColumn,
styles.pokemonInfoLeftColumn
);
const leagueRightColumnCss = classNames(
styles.rightColumn,
);
const pokemonInfoWrapper = classNames(
styles.container,
styles.pokemonInfoWrapper
);
return ( return (
<React.Fragment> <React.Fragment>
<div className={ wrapperCss }> <div className={ wrapperCss }>
@ -194,104 +39,16 @@ export class PokemonExplorer extends React.Component<IPokemonExplorerProps, ISta
leaguePokemon={ leaguePokemon } leaguePokemon={ leaguePokemon }
temporaryNavigationIsActive={ temporaryNavigationIsActive } temporaryNavigationIsActive={ temporaryNavigationIsActive }
/> />
<LeagueSelector <LeagueIvExplorer
activeLeague={ activeLeague } activeLeague={ activeLeague }
handleLeagueSelect={ this.handleLeagueSelect } leaguePokemon={ leaguePokemon }
individualValues={ individualValues }
handleChangeIndividualValue={ handleChangeIndividualValue }
handleMaximizeLevel={ handleMaximizeLevel }
handleChangeLeague={ handleChangeLeague }
/> />
<section className={ formContainerCss }>
<h5 className={ ivContainerTitleCss }>
<span>IVs</span>
<label>
<input
className="nes-radio"
type="radio"
value="manual"
checked={ ivDisplayMode === IvDisplayMode.MANUAL }
onChange={ this.handleIvDisplayModeManual }
/> <span>Manual</span>
</label>
<label>
<input
className="nes-radio"
type="radio"
value="list"
checked={ ivDisplayMode === IvDisplayMode.LIST }
onChange={ this.handleIvDisplayModeList }
/> <span>List</span>
</label>
</h5>
{ ivDisplayMode === IvDisplayMode.MANUAL &&
<IvForm
ivs={ individualValues }
placeholder={ leaguePokemon.pvp[activeLeague][0] }
handleChangeIndividualValue={ handleChangeIndividualValue }
handleMaximizeLevel={ handleMaximizeLevel }
/>
}
{ ivDisplayMode === IvDisplayMode.LIST &&
<LeagueStatsList
activePokemonId={ leaguePokemon.id }
activePokemonForm={ leaguePokemon.form }
activeIndividualValues={ individualValues }
leagueStatsList={ leaguePokemon.pvp[activeLeague] }
handleActivateLeagueStats={ this.handleActivateLeagueStats }
/>
}
</section>
<section className={ leaugeRankCss }>
<h5 className={ containerTitleCss }>Rank</h5>
<div className={ pokemonInfoWrapper }>
<div className={ leagueLeftColumnCss }>
{ rankedPokemon === null || rankedPokemon.cp > MaxCpByLeague[activeLeague] &&
<div><h1 className={ styles.pokemonRankValue }>N/A</h1></div>
}
{ rankedPokemon !== null && rankedPokemon.cp <= MaxCpByLeague[activeLeague] &&
<div><h1 className={ styles.pokemonRankValue }>{ rankedGrade }</h1> Rank</div>
}
<div>CP <h1 className={ styles.pokemonRankValue }>{ rankedCp }</h1></div>
</div>
<div className={ leagueRightColumnCss }>
<StatDisplay
statLabel={ `HP${ String.fromCharCode(160) }` }
statValue={ rankedHp }
statRank={ staminaStatRank }
/>
<StatDisplay
statLabel="ATK"
statValue={ rankedAtk }
statRank={ attackStatRank }
/>
<StatDisplay
statLabel="DEF"
statValue={ rankedDef }
statRank={ defenseStatRank }
/>
</div>
</div>
</section>
</div> </div>
</React.Fragment> </React.Fragment>
); );
} }
private readonly handleActivateLeagueStats = (stats : IStats) => {
const { handleChangeIndividualValue } = this.props;
handleChangeIndividualValue('level', stats.level);
handleChangeIndividualValue('hp', stats.ivHp);
handleChangeIndividualValue('atk', stats.ivAtk);
handleChangeIndividualValue('def', stats.ivDef);
}
private readonly handleLeagueSelect = (league : League) => {
this.props.handleChangeLeague(league);
}
private readonly handleIvDisplayModeManual = () => {
this.setState({ ivDisplayMode: IvDisplayMode.MANUAL });
}
private readonly handleIvDisplayModeList = () => {
this.setState({ ivDisplayMode: IvDisplayMode.LIST });
}
} }

View File

@ -0,0 +1,74 @@
@import '~styles/Variables.scss';
.container {
composes: container from './PokemonExplorer.scss';
margin-bottom: 1rem;
}
.leftColumn {
composes: leftColumn from './PokemonExplorer.scss';
}
.rightColumn {
composes: rightColumn from './PokemonExplorer.scss';
}
.leaguePokemonRank {
justify-content: flex-start;
flex-wrap: wrap;
.pokemonInfoWrapper {
flex: 1 0 100%;
display: flex;
}
.leftColumn {
align-items: flex-start;
}
.pokemonRankValue {
display: inline;
}
}
.ivsContainer {
flex: 0 999 auto;
display: flex;
flex-flow: column nowrap;
/* for Firefox */
// min-height: 0;
:global(.title).ivContainerTitle {
display: flex;
justify-content: flex-end;
background-color: transparent;
padding: 0;
& > * {
background-color: $main-background-color;
&:first-child {
margin-right: auto;
padding: 0 0.5em;
}
&:last-child {
padding-right: 0.5em;
}
}
}
&.diplayingIvList {
$border-offset: 8px;
padding: 1.5rem 0 0;
:global(.title).ivContainerTitle {
margin-bottom: 0;
margin-right: -$border-offset;
margin-left: -$border-offset;
padding: 0 2.5rem;
}
}
}

View File

@ -0,0 +1,11 @@
// This file is automatically generated.
// Please do not change this file!
export const container: string;
export const diplayingIvList: string;
export const ivContainerTitle: string;
export const ivsContainer: string;
export const leaguePokemonRank: string;
export const leftColumn: string;
export const pokemonInfoWrapper: string;
export const pokemonRankValue: string;
export const rightColumn: string;

View File

@ -29,63 +29,3 @@
align-items: start; align-items: start;
} }
} }
.leaguePokemonRank {
justify-content: flex-start;
flex-wrap: wrap;
.pokemonInfoWrapper {
flex: 1 0 100%;
display: flex;
}
.pokemonInfoLeftColumn {
align-items: flex-start;
}
.pokemonRankValue {
display: inline;
}
}
.ivsContainer {
flex: 0 999 auto;
display: flex;
flex-flow: column nowrap;
/* for Firefox */
// min-height: 0;
:global(.title).ivContainerTitle {
display: flex;
justify-content: flex-end;
background-color: transparent;
padding: 0;
& > * {
background-color: $main-background-color;
&:first-child {
margin-right: auto;
padding: 0 0.5em;
}
&:last-child {
padding-right: 0.5em;
}
}
}
&.diplayingIvList {
$border-offset: 8px;
padding: 1.5rem 0 0;
:global(.title).ivContainerTitle {
margin-bottom: 0;
margin-right: -$border-offset;
margin-left: -$border-offset;
padding: 0 2.5rem;
}
}
}

View File

@ -1,13 +1,6 @@
// This file is automatically generated. // This file is automatically generated.
// Please do not change this file! // Please do not change this file!
export const container: string; export const container: string;
export const diplayingIvList: string;
export const ivContainerTitle: string;
export const ivsContainer: string;
export const leaguePokemonRank: string;
export const leftColumn: string; export const leftColumn: string;
export const pokemonInfoLeftColumn: string;
export const pokemonInfoWrapper: string;
export const pokemonRankValue: string;
export const rightColumn: string; export const rightColumn: string;
export const wrapper: string; export const wrapper: string;