finish type coverage functionality

This commit is contained in:
Jeff Colombo 2019-03-13 01:28:56 -04:00
parent ca3629f255
commit 2100315c80
13 changed files with 535 additions and 215 deletions

112
dist/app.css vendored
View File

@ -267,91 +267,145 @@
background-color: #a8a878; } background-color: #a8a878; }
.TypeIndicator__pokemonType__3MOQI.normal::after { .TypeIndicator__pokemonType__3MOQI.normal::after {
box-shadow: 0 -4px #a8a878, 0 -8px, 4px 0 #a8a878, 4px -4px, 8px 0, 0 4px #a8a878, 0 8px, -4px 0 #a8a878, -4px 4px, -8px 0, -4px -4px, 4px 4px; } box-shadow: 0 -4px #a8a878, 0 -8px, 4px 0 #a8a878, 4px -4px, 8px 0, 0 4px #a8a878, 0 8px, -4px 0 #a8a878, -4px 4px, -8px 0, -4px -4px, 4px 4px; }
.TypeIndicator__pokemonType__3MOQI.normal.outline {
color: #a8a878;
background-color: #fff; }
.TypeIndicator__pokemonType__3MOQI.fighting { .TypeIndicator__pokemonType__3MOQI.fighting {
color: #fff; color: #fff;
background-color: #c03028; } background-color: #c03028; }
.TypeIndicator__pokemonType__3MOQI.fighting::after { .TypeIndicator__pokemonType__3MOQI.fighting::after {
box-shadow: 0 -4px #c03028, 0 -8px, 4px 0 #c03028, 4px -4px, 8px 0, 0 4px #c03028, 0 8px, -4px 0 #c03028, -4px 4px, -8px 0, -4px -4px, 4px 4px; } box-shadow: 0 -4px #c03028, 0 -8px, 4px 0 #c03028, 4px -4px, 8px 0, 0 4px #c03028, 0 8px, -4px 0 #c03028, -4px 4px, -8px 0, -4px -4px, 4px 4px; }
.TypeIndicator__pokemonType__3MOQI.fighting.outline {
color: #c03028;
background-color: #fff; }
.TypeIndicator__pokemonType__3MOQI.flying { .TypeIndicator__pokemonType__3MOQI.flying {
color: #fff; color: #fff;
background-color: #a890f0; } background-color: #a890f0; }
.TypeIndicator__pokemonType__3MOQI.flying::after { .TypeIndicator__pokemonType__3MOQI.flying::after {
box-shadow: 0 -4px #a890f0, 0 -8px, 4px 0 #a890f0, 4px -4px, 8px 0, 0 4px #a890f0, 0 8px, -4px 0 #a890f0, -4px 4px, -8px 0, -4px -4px, 4px 4px; } box-shadow: 0 -4px #a890f0, 0 -8px, 4px 0 #a890f0, 4px -4px, 8px 0, 0 4px #a890f0, 0 8px, -4px 0 #a890f0, -4px 4px, -8px 0, -4px -4px, 4px 4px; }
.TypeIndicator__pokemonType__3MOQI.flying.outline {
color: #a890f0;
background-color: #fff; }
.TypeIndicator__pokemonType__3MOQI.poison { .TypeIndicator__pokemonType__3MOQI.poison {
color: #fff; color: #fff;
background-color: #a040a0; } background-color: #a040a0; }
.TypeIndicator__pokemonType__3MOQI.poison::after { .TypeIndicator__pokemonType__3MOQI.poison::after {
box-shadow: 0 -4px #a040a0, 0 -8px, 4px 0 #a040a0, 4px -4px, 8px 0, 0 4px #a040a0, 0 8px, -4px 0 #a040a0, -4px 4px, -8px 0, -4px -4px, 4px 4px; } box-shadow: 0 -4px #a040a0, 0 -8px, 4px 0 #a040a0, 4px -4px, 8px 0, 0 4px #a040a0, 0 8px, -4px 0 #a040a0, -4px 4px, -8px 0, -4px -4px, 4px 4px; }
.TypeIndicator__pokemonType__3MOQI.poison.outline {
color: #a040a0;
background-color: #fff; }
.TypeIndicator__pokemonType__3MOQI.ground { .TypeIndicator__pokemonType__3MOQI.ground {
color: #fff; color: #fff;
background-color: #e0c068; } background-color: #e0c068; }
.TypeIndicator__pokemonType__3MOQI.ground::after { .TypeIndicator__pokemonType__3MOQI.ground::after {
box-shadow: 0 -4px #e0c068, 0 -8px, 4px 0 #e0c068, 4px -4px, 8px 0, 0 4px #e0c068, 0 8px, -4px 0 #e0c068, -4px 4px, -8px 0, -4px -4px, 4px 4px; } box-shadow: 0 -4px #e0c068, 0 -8px, 4px 0 #e0c068, 4px -4px, 8px 0, 0 4px #e0c068, 0 8px, -4px 0 #e0c068, -4px 4px, -8px 0, -4px -4px, 4px 4px; }
.TypeIndicator__pokemonType__3MOQI.ground.outline {
color: #e0c068;
background-color: #fff; }
.TypeIndicator__pokemonType__3MOQI.rock { .TypeIndicator__pokemonType__3MOQI.rock {
color: #fff; color: #fff;
background-color: #b8a038; } background-color: #b8a038; }
.TypeIndicator__pokemonType__3MOQI.rock::after { .TypeIndicator__pokemonType__3MOQI.rock::after {
box-shadow: 0 -4px #b8a038, 0 -8px, 4px 0 #b8a038, 4px -4px, 8px 0, 0 4px #b8a038, 0 8px, -4px 0 #b8a038, -4px 4px, -8px 0, -4px -4px, 4px 4px; } box-shadow: 0 -4px #b8a038, 0 -8px, 4px 0 #b8a038, 4px -4px, 8px 0, 0 4px #b8a038, 0 8px, -4px 0 #b8a038, -4px 4px, -8px 0, -4px -4px, 4px 4px; }
.TypeIndicator__pokemonType__3MOQI.rock.outline {
color: #b8a038;
background-color: #fff; }
.TypeIndicator__pokemonType__3MOQI.bug { .TypeIndicator__pokemonType__3MOQI.bug {
color: #fff; color: #fff;
background-color: #a8b820; } background-color: #a8b820; }
.TypeIndicator__pokemonType__3MOQI.bug::after { .TypeIndicator__pokemonType__3MOQI.bug::after {
box-shadow: 0 -4px #a8b820, 0 -8px, 4px 0 #a8b820, 4px -4px, 8px 0, 0 4px #a8b820, 0 8px, -4px 0 #a8b820, -4px 4px, -8px 0, -4px -4px, 4px 4px; } box-shadow: 0 -4px #a8b820, 0 -8px, 4px 0 #a8b820, 4px -4px, 8px 0, 0 4px #a8b820, 0 8px, -4px 0 #a8b820, -4px 4px, -8px 0, -4px -4px, 4px 4px; }
.TypeIndicator__pokemonType__3MOQI.bug.outline {
color: #a8b820;
background-color: #fff; }
.TypeIndicator__pokemonType__3MOQI.ghost { .TypeIndicator__pokemonType__3MOQI.ghost {
color: #fff; color: #fff;
background-color: #705898; } background-color: #705898; }
.TypeIndicator__pokemonType__3MOQI.ghost::after { .TypeIndicator__pokemonType__3MOQI.ghost::after {
box-shadow: 0 -4px #705898, 0 -8px, 4px 0 #705898, 4px -4px, 8px 0, 0 4px #705898, 0 8px, -4px 0 #705898, -4px 4px, -8px 0, -4px -4px, 4px 4px; } box-shadow: 0 -4px #705898, 0 -8px, 4px 0 #705898, 4px -4px, 8px 0, 0 4px #705898, 0 8px, -4px 0 #705898, -4px 4px, -8px 0, -4px -4px, 4px 4px; }
.TypeIndicator__pokemonType__3MOQI.ghost.outline {
color: #705898;
background-color: #fff; }
.TypeIndicator__pokemonType__3MOQI.steel { .TypeIndicator__pokemonType__3MOQI.steel {
color: #fff; color: #fff;
background-color: #b8b8d0; } background-color: #b8b8d0; }
.TypeIndicator__pokemonType__3MOQI.steel::after { .TypeIndicator__pokemonType__3MOQI.steel::after {
box-shadow: 0 -4px #b8b8d0, 0 -8px, 4px 0 #b8b8d0, 4px -4px, 8px 0, 0 4px #b8b8d0, 0 8px, -4px 0 #b8b8d0, -4px 4px, -8px 0, -4px -4px, 4px 4px; } box-shadow: 0 -4px #b8b8d0, 0 -8px, 4px 0 #b8b8d0, 4px -4px, 8px 0, 0 4px #b8b8d0, 0 8px, -4px 0 #b8b8d0, -4px 4px, -8px 0, -4px -4px, 4px 4px; }
.TypeIndicator__pokemonType__3MOQI.steel.outline {
color: #b8b8d0;
background-color: #fff; }
.TypeIndicator__pokemonType__3MOQI.fire { .TypeIndicator__pokemonType__3MOQI.fire {
color: #fff; color: #fff;
background-color: #f08030; } background-color: #f08030; }
.TypeIndicator__pokemonType__3MOQI.fire::after { .TypeIndicator__pokemonType__3MOQI.fire::after {
box-shadow: 0 -4px #f08030, 0 -8px, 4px 0 #f08030, 4px -4px, 8px 0, 0 4px #f08030, 0 8px, -4px 0 #f08030, -4px 4px, -8px 0, -4px -4px, 4px 4px; } box-shadow: 0 -4px #f08030, 0 -8px, 4px 0 #f08030, 4px -4px, 8px 0, 0 4px #f08030, 0 8px, -4px 0 #f08030, -4px 4px, -8px 0, -4px -4px, 4px 4px; }
.TypeIndicator__pokemonType__3MOQI.fire.outline {
color: #f08030;
background-color: #fff; }
.TypeIndicator__pokemonType__3MOQI.water { .TypeIndicator__pokemonType__3MOQI.water {
color: #fff; color: #fff;
background-color: #6890f0; } background-color: #6890f0; }
.TypeIndicator__pokemonType__3MOQI.water::after { .TypeIndicator__pokemonType__3MOQI.water::after {
box-shadow: 0 -4px #6890f0, 0 -8px, 4px 0 #6890f0, 4px -4px, 8px 0, 0 4px #6890f0, 0 8px, -4px 0 #6890f0, -4px 4px, -8px 0, -4px -4px, 4px 4px; } box-shadow: 0 -4px #6890f0, 0 -8px, 4px 0 #6890f0, 4px -4px, 8px 0, 0 4px #6890f0, 0 8px, -4px 0 #6890f0, -4px 4px, -8px 0, -4px -4px, 4px 4px; }
.TypeIndicator__pokemonType__3MOQI.water.outline {
color: #6890f0;
background-color: #fff; }
.TypeIndicator__pokemonType__3MOQI.grass { .TypeIndicator__pokemonType__3MOQI.grass {
color: #fff; color: #fff;
background-color: #78c850; } background-color: #78c850; }
.TypeIndicator__pokemonType__3MOQI.grass::after { .TypeIndicator__pokemonType__3MOQI.grass::after {
box-shadow: 0 -4px #78c850, 0 -8px, 4px 0 #78c850, 4px -4px, 8px 0, 0 4px #78c850, 0 8px, -4px 0 #78c850, -4px 4px, -8px 0, -4px -4px, 4px 4px; } box-shadow: 0 -4px #78c850, 0 -8px, 4px 0 #78c850, 4px -4px, 8px 0, 0 4px #78c850, 0 8px, -4px 0 #78c850, -4px 4px, -8px 0, -4px -4px, 4px 4px; }
.TypeIndicator__pokemonType__3MOQI.grass.outline {
color: #78c850;
background-color: #fff; }
.TypeIndicator__pokemonType__3MOQI.electric { .TypeIndicator__pokemonType__3MOQI.electric {
color: #fff; color: #fff;
background-color: #f8d030; } background-color: #f8d030; }
.TypeIndicator__pokemonType__3MOQI.electric::after { .TypeIndicator__pokemonType__3MOQI.electric::after {
box-shadow: 0 -4px #f8d030, 0 -8px, 4px 0 #f8d030, 4px -4px, 8px 0, 0 4px #f8d030, 0 8px, -4px 0 #f8d030, -4px 4px, -8px 0, -4px -4px, 4px 4px; } box-shadow: 0 -4px #f8d030, 0 -8px, 4px 0 #f8d030, 4px -4px, 8px 0, 0 4px #f8d030, 0 8px, -4px 0 #f8d030, -4px 4px, -8px 0, -4px -4px, 4px 4px; }
.TypeIndicator__pokemonType__3MOQI.electric.outline {
color: #f8d030;
background-color: #fff; }
.TypeIndicator__pokemonType__3MOQI.psychic { .TypeIndicator__pokemonType__3MOQI.psychic {
color: #fff; color: #fff;
background-color: #f85888; } background-color: #f85888; }
.TypeIndicator__pokemonType__3MOQI.psychic::after { .TypeIndicator__pokemonType__3MOQI.psychic::after {
box-shadow: 0 -4px #f85888, 0 -8px, 4px 0 #f85888, 4px -4px, 8px 0, 0 4px #f85888, 0 8px, -4px 0 #f85888, -4px 4px, -8px 0, -4px -4px, 4px 4px; } box-shadow: 0 -4px #f85888, 0 -8px, 4px 0 #f85888, 4px -4px, 8px 0, 0 4px #f85888, 0 8px, -4px 0 #f85888, -4px 4px, -8px 0, -4px -4px, 4px 4px; }
.TypeIndicator__pokemonType__3MOQI.psychic.outline {
color: #f85888;
background-color: #fff; }
.TypeIndicator__pokemonType__3MOQI.ice { .TypeIndicator__pokemonType__3MOQI.ice {
color: #fff; color: #fff;
background-color: #98d8d8; } background-color: #98d8d8; }
.TypeIndicator__pokemonType__3MOQI.ice::after { .TypeIndicator__pokemonType__3MOQI.ice::after {
box-shadow: 0 -4px #98d8d8, 0 -8px, 4px 0 #98d8d8, 4px -4px, 8px 0, 0 4px #98d8d8, 0 8px, -4px 0 #98d8d8, -4px 4px, -8px 0, -4px -4px, 4px 4px; } box-shadow: 0 -4px #98d8d8, 0 -8px, 4px 0 #98d8d8, 4px -4px, 8px 0, 0 4px #98d8d8, 0 8px, -4px 0 #98d8d8, -4px 4px, -8px 0, -4px -4px, 4px 4px; }
.TypeIndicator__pokemonType__3MOQI.ice.outline {
color: #98d8d8;
background-color: #fff; }
.TypeIndicator__pokemonType__3MOQI.dragon { .TypeIndicator__pokemonType__3MOQI.dragon {
color: #fff; color: #fff;
background-color: #6f35fc; } background-color: #6f35fc; }
.TypeIndicator__pokemonType__3MOQI.dragon::after { .TypeIndicator__pokemonType__3MOQI.dragon::after {
box-shadow: 0 -4px #6f35fc, 0 -8px, 4px 0 #6f35fc, 4px -4px, 8px 0, 0 4px #6f35fc, 0 8px, -4px 0 #6f35fc, -4px 4px, -8px 0, -4px -4px, 4px 4px; } box-shadow: 0 -4px #6f35fc, 0 -8px, 4px 0 #6f35fc, 4px -4px, 8px 0, 0 4px #6f35fc, 0 8px, -4px 0 #6f35fc, -4px 4px, -8px 0, -4px -4px, 4px 4px; }
.TypeIndicator__pokemonType__3MOQI.dragon.outline {
color: #6f35fc;
background-color: #fff; }
.TypeIndicator__pokemonType__3MOQI.dark { .TypeIndicator__pokemonType__3MOQI.dark {
color: #fff; color: #fff;
background-color: #705848; } background-color: #705848; }
.TypeIndicator__pokemonType__3MOQI.dark::after { .TypeIndicator__pokemonType__3MOQI.dark::after {
box-shadow: 0 -4px #705848, 0 -8px, 4px 0 #705848, 4px -4px, 8px 0, 0 4px #705848, 0 8px, -4px 0 #705848, -4px 4px, -8px 0, -4px -4px, 4px 4px; } box-shadow: 0 -4px #705848, 0 -8px, 4px 0 #705848, 4px -4px, 8px 0, 0 4px #705848, 0 8px, -4px 0 #705848, -4px 4px, -8px 0, -4px -4px, 4px 4px; }
.TypeIndicator__pokemonType__3MOQI.dark.outline {
color: #705848;
background-color: #fff; }
.TypeIndicator__pokemonType__3MOQI.fairy { .TypeIndicator__pokemonType__3MOQI.fairy {
color: #fff; color: #fff;
background-color: #ee99ac; } background-color: #ee99ac; }
.TypeIndicator__pokemonType__3MOQI.fairy::after { .TypeIndicator__pokemonType__3MOQI.fairy::after {
box-shadow: 0 -4px #ee99ac, 0 -8px, 4px 0 #ee99ac, 4px -4px, 8px 0, 0 4px #ee99ac, 0 8px, -4px 0 #ee99ac, -4px 4px, -8px 0, -4px -4px, 4px 4px; } box-shadow: 0 -4px #ee99ac, 0 -8px, 4px 0 #ee99ac, 4px -4px, 8px 0, 0 4px #ee99ac, 0 8px, -4px 0 #ee99ac, -4px 4px, -8px 0, -4px -4px, 4px 4px; }
.TypeIndicator__pokemonType__3MOQI.fairy.outline {
color: #ee99ac;
background-color: #fff; }
.MovesExplorer__wrapper__2y-BK { .MovesExplorer__wrapper__2y-BK {
font-size: 1em; } font-size: 1em; }
@ -396,51 +450,50 @@
.MovesDropdown__legacy__3-s2n { } .MovesDropdown__legacy__3-s2n { }
.TypeEffectiveDisplay__multiplierWrapper__14os7 { .TypeEffectiveDisplay__typeWrapper__3w4wT,
.TypeEffectiveDisplay__typeMultiplierWrapper__1WOCi {
position: relative; position: relative;
z-index: 0; z-index: 0; }
.TypeEffectiveDisplay__typeMultiplierWrapper__1WOCi {
padding-top: 6px; padding-top: 6px;
padding-right: 6px; } padding-right: 6px; }
.TypeEffectiveDisplay__multiplierWrapper__14os7 > * { .TypeEffectiveDisplay__typeMultiplierWrapper__1WOCi > * {
position: absolute; } position: absolute; }
.TypeEffectiveDisplay__multiplierWrapper__14os7 :nth-child(1) { .TypeEffectiveDisplay__typeMultiplierWrapper__1WOCi :nth-child(1) {
position: inherit; position: inherit;
z-index: 3; } z-index: 3; }
.TypeEffectiveDisplay__multiplierWrapper__14os7 :nth-child(2) { .TypeEffectiveDisplay__typeMultiplierWrapper__1WOCi :nth-child(2) {
top: 0; top: 0;
left: 6px; left: 6px;
z-index: 2; } z-index: 2; }
.TypeEffectiveDisplay__multiplierWrapper__14os7 :nth-child(3) { .TypeEffectiveDisplay__typeMultiplierWrapper__1WOCi :nth-child(3) {
left: 12px; left: 12px;
z-index: 1; } z-index: 1; }
.TypeEffectiveDisplay__multiplierWrapper__14os7 :nth-child(4) { .TypeEffectiveDisplay__typeMultiplierWrapper__1WOCi :nth-child(4) {
left: 18px; left: 18px;
z-index: 0; } z-index: 0; }
.TypeEffectiveDisplay__multiplierWrapper__14os7.TypeEffectiveDisplay__multiplierWrapperX3__1SBG1 { .TypeEffectiveDisplay__typeMultiplierWrapper__1WOCi.TypeEffectiveDisplay__typeMultiplierWrapperX3__35-RS {
padding-top: 12px; padding-top: 12px;
padding-right: 12px; } padding-right: 12px; }
.TypeEffectiveDisplay__multiplierWrapper__14os7.TypeEffectiveDisplay__multiplierWrapperX3__1SBG1 :nth-child(3) { .TypeEffectiveDisplay__typeMultiplierWrapper__1WOCi.TypeEffectiveDisplay__typeMultiplierWrapperX3__35-RS :nth-child(3) {
top: 0; } top: 0; }
.TypeEffectiveDisplay__multiplierWrapper__14os7.TypeEffectiveDisplay__multiplierWrapperX3__1SBG1 :nth-child(2) { .TypeEffectiveDisplay__typeMultiplierWrapper__1WOCi.TypeEffectiveDisplay__typeMultiplierWrapperX3__35-RS :nth-child(2) {
top: 6px; } top: 6px; }
.TypeEffectiveDisplay__multiplierWrapper__14os7.TypeEffectiveDisplay__multiplierWrapperX4__2KqYa { .TypeEffectiveDisplay__typeMultiplierWrapper__1WOCi.TypeEffectiveDisplay__typeMultiplierWrapperX4__2Onf7 {
padding-top: 18px; padding-top: 18px;
padding-right: 18px; } padding-right: 18px; }
.TypeEffectiveDisplay__multiplierWrapper__14os7.TypeEffectiveDisplay__multiplierWrapperX4__2KqYa :nth-child(4) { .TypeEffectiveDisplay__typeMultiplierWrapper__1WOCi.TypeEffectiveDisplay__typeMultiplierWrapperX4__2Onf7 :nth-child(4) {
top: 0; } top: 0; }
.TypeEffectiveDisplay__multiplierWrapper__14os7.TypeEffectiveDisplay__multiplierWrapperX4__2KqYa :nth-child(3) { .TypeEffectiveDisplay__typeMultiplierWrapper__1WOCi.TypeEffectiveDisplay__typeMultiplierWrapperX4__2Onf7 :nth-child(3) {
top: 6px; } top: 6px; }
.TypeEffectiveDisplay__multiplierWrapper__14os7.TypeEffectiveDisplay__multiplierWrapperX4__2KqYa :nth-child(2) { .TypeEffectiveDisplay__typeMultiplierWrapper__1WOCi.TypeEffectiveDisplay__typeMultiplierWrapperX4__2Onf7 :nth-child(2) {
top: 12px; } top: 12px; }
.TypeEffectiveDisplay__wrapper__1FFIj { .TypeEffectiveDisplay__wrapper__1FFIj {
margin: 0 1em; } margin: 0 1em; }
.TypeEffectiveDisplay__wrapper__1FFIj * + h4 { .TypeEffectiveDisplay__wrapper__1FFIj * + h4 {
margin-top: 1em; } margin-top: 1em; }
.TypeEffectiveDisplay__wrapper__1FFIj h4 p {
font-size: 0.7em;
color: #b6b6b6;
margin: 0; }
.TypeEffectiveDisplay__wrapper__1FFIj .TypeEffectiveDisplay__indicatorWrapper__2F3AY { .TypeEffectiveDisplay__wrapper__1FFIj .TypeEffectiveDisplay__indicatorWrapper__2F3AY {
display: flex; display: flex;
flex-flow: row wrap; flex-flow: row wrap;
@ -448,18 +501,31 @@
.TypeEffectiveDisplay__wrapper__1FFIj .TypeEffectiveDisplay__indicatorWrapper__2F3AY > * { .TypeEffectiveDisplay__wrapper__1FFIj .TypeEffectiveDisplay__indicatorWrapper__2F3AY > * {
margin-right: 14px; margin-right: 14px;
height: 0%; } height: 0%; }
.TypeEffectiveDisplay__wrapper__1FFIj .TypeEffectiveDisplay__indicatorWrapper__2F3AY .TypeEffectiveDisplay__multiplierWrapper__14os7 { .TypeEffectiveDisplay__wrapper__1FFIj .TypeEffectiveDisplay__indicatorWrapper__2F3AY .TypeEffectiveDisplay__typeMultiplierWrapper__1WOCi {
width: auto; width: auto;
margin-right: 2px; } margin-right: 2px; }
.TypeEffectiveDisplay__wrapper__1FFIj .TypeEffectiveDisplay__indicatorWrapper__2F3AY .TypeEffectiveDisplay__multiplierWrapper__14os7.TypeEffectiveDisplay__multiplierWrapperX3__1SBG1 { .TypeEffectiveDisplay__wrapper__1FFIj .TypeEffectiveDisplay__indicatorWrapper__2F3AY .TypeEffectiveDisplay__typeMultiplierWrapper__1WOCi.TypeEffectiveDisplay__typeMultiplierWrapperX3__35-RS {
margin-right: -4px; } margin-right: -4px; }
.TypeEffectiveDisplay__wrapper__1FFIj .TypeEffectiveDisplay__indicatorWrapper__2F3AY .TypeEffectiveDisplay__multiplierWrapper__14os7.TypeEffectiveDisplay__multiplierWrapperX4__2KqYa { .TypeEffectiveDisplay__wrapper__1FFIj .TypeEffectiveDisplay__indicatorWrapper__2F3AY .TypeEffectiveDisplay__typeMultiplierWrapper__1WOCi.TypeEffectiveDisplay__typeMultiplierWrapperX4__2Onf7 {
margin-right: -10px; } margin-right: -10px; }
.TypeEffectiveDisplay__wrapper__1FFIj .TypeEffectiveDisplay__indicatorWrapper__2F3AY > *, .TypeEffectiveDisplay__wrapper__1FFIj .TypeEffectiveDisplay__indicatorWrapper__2F3AY .TypeEffectiveDisplay__typeWrapper__3w4wT > *,
.TypeEffectiveDisplay__wrapper__1FFIj .TypeEffectiveDisplay__indicatorWrapper__2F3AY .TypeEffectiveDisplay__multiplierWrapper__14os7 > * { .TypeEffectiveDisplay__wrapper__1FFIj .TypeEffectiveDisplay__indicatorWrapper__2F3AY .TypeEffectiveDisplay__typeMultiplierWrapper__1WOCi > * {
flex-basis: unset; flex-basis: unset;
width: 6.75rem; } width: 6.75rem; }
.TypeEffectiveDisplay__isCovered__3qyUq {
position: relative; }
.TypeEffectiveDisplay__isCovered__3qyUq::before {
content: "";
position: absolute;
right: 25px;
bottom: 20px;
z-index: 10;
width: 2px;
height: 2px;
color: #92cc41;
box-shadow: 18px 2px, 20px 2px, 16px 4px, 18px 4px, 20px 4px, 2px 6px, 14px 6px, 16px 6px, 2px 8px, 4px 8px, 12px 8px, 14px 8px, 4px 10px, 6px 10px, 10px 10px, 12px 10px, 6px 12px, 8px 12px, 10px 12px, 8px 14px; }
.MovesExplorer__wrapper__2y-BK { .MovesExplorer__wrapper__2y-BK {
font-size: 1em; } font-size: 1em; }
.MovesExplorer__wrapper__2y-BK .title { .MovesExplorer__wrapper__2y-BK .title {

304
dist/main-bundle.js vendored
View File

@ -29619,7 +29619,7 @@ function pathToRegexp (path, keys, options) {
/*! ModuleConcatenation bailout: Cannot concat with ./node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js because of ./node_modules/react-redux/es/index.js */ /*! ModuleConcatenation bailout: Cannot concat with ./node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js because of ./node_modules/react-redux/es/index.js */
/*! ModuleConcatenation bailout: Cannot concat with ./node_modules/@babel/runtime/helpers/esm/extends.js because of ./node_modules/react-redux/es/index.js */ /*! ModuleConcatenation bailout: Cannot concat with ./node_modules/@babel/runtime/helpers/esm/extends.js because of ./node_modules/react-redux/es/index.js */
/*! ModuleConcatenation bailout: Cannot concat with ./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js because of ./node_modules/react-redux/es/index.js */ /*! ModuleConcatenation bailout: Cannot concat with ./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js because of ./node_modules/react-redux/es/index.js */
/*! ModuleConcatenation bailout: Cannot concat with ./node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js because of ./node_modules/react-measure/dist/index.esm.js */ /*! ModuleConcatenation bailout: Cannot concat with ./node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js because of ./node_modules/react-redux/es/index.js */
/*! ModuleConcatenation bailout: Cannot concat with ./node_modules/react/index.js (<- Module is not an ECMAScript module) */ /*! ModuleConcatenation bailout: Cannot concat with ./node_modules/react/index.js (<- Module is not an ECMAScript module) */
/***/ (function(module, __webpack_exports__, __webpack_require__) { /***/ (function(module, __webpack_exports__, __webpack_require__) {
@ -38391,7 +38391,8 @@ function (_react_1$default$Comp) {
onClick: onClick onClick: onClick
}, react_1.default.createElement("span", null, moveStats.name), react_1.default.createElement(TypeIndicator_1.TypeIndicator, { }, react_1.default.createElement("span", null, moveStats.name), react_1.default.createElement(TypeIndicator_1.TypeIndicator, {
className: typeCss, className: typeCss,
type: moveStats.type type: moveStats.type,
theme: TypeIndicator_1.TypeTheme.SOLID
}))); })));
} }
}], [{ }], [{
@ -38472,14 +38473,14 @@ 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 Pokemon_1 = __webpack_require__(/*! app/models/Pokemon */ "./src/ts/app/models/Pokemon.ts");
var MovesDropdown_1 = __webpack_require__(/*! app/components/PokemonExplorer/MovesDropdown */ "./src/ts/app/components/PokemonExplorer/MovesDropdown.tsx"); var MovesDropdown_1 = __webpack_require__(/*! app/components/PokemonExplorer/MovesDropdown */ "./src/ts/app/components/PokemonExplorer/MovesDropdown.tsx");
var TypeEffectiveDisplay_1 = __webpack_require__(/*! ./TypeEffectiveDisplay */ "./src/ts/app/components/PokemonExplorer/TypeEffectiveDisplay.tsx"); var TypeEffectiveDisplay_1 = __webpack_require__(/*! ./TypeEffectiveDisplay */ "./src/ts/app/components/PokemonExplorer/TypeEffectiveDisplay.tsx");
var TypeIndicator_1 = __webpack_require__(/*! ./TypeIndicator */ "./src/ts/app/components/PokemonExplorer/TypeIndicator.tsx"); var TypeIndicator_1 = __webpack_require__(/*! ./TypeIndicator */ "./src/ts/app/components/PokemonExplorer/TypeIndicator.tsx");
var types_1 = __webpack_require__(/*! app/utils/types */ "./src/ts/app/utils/types.ts");
var styles = __importStar(__webpack_require__(/*! app/components/PokemonExplorer/styles/MovesExplorer.scss */ "./src/ts/app/components/PokemonExplorer/styles/MovesExplorer.scss")); var styles = __importStar(__webpack_require__(/*! app/components/PokemonExplorer/styles/MovesExplorer.scss */ "./src/ts/app/components/PokemonExplorer/styles/MovesExplorer.scss"));
var MovesExplorer = var MovesExplorer =
@ -38497,40 +38498,9 @@ function (_react_1$default$Comp) {
_this.calculateTypeCoverage = function () { _this.calculateTypeCoverage = function () {
var _this$props = _this.props, var _this$props = _this.props,
selectedMoves = _this$props.selectedMoves, selectedMoves = _this$props.selectedMoves,
movesById = _this$props.movesById,
attackTypeEffectiveness = _this$props.attackTypeEffectiveness; attackTypeEffectiveness = _this$props.attackTypeEffectiveness;
var calculatedffectiveness = new Map(); return types_1.calculateTypeCoverage(selectedMoves, movesById, attackTypeEffectiveness);
Object.values(selectedMoves).forEach(function (move) {
var moveType = _this.getMoveType(move);
if (moveType !== null) {
var moveEffectiveness = attackTypeEffectiveness.get(moveType);
if (typeof moveEffectiveness !== 'undefined') {
moveEffectiveness.forEach(function (effectiveness, type) {
var currentEffectiveness = calculatedffectiveness.get(type);
if (typeof currentEffectiveness === 'undefined' || Pokemon_1.TypeEffectiveness[effectiveness] > Pokemon_1.TypeEffectiveness[currentEffectiveness]) {
calculatedffectiveness.set(type, effectiveness);
}
});
}
}
});
return calculatedffectiveness;
};
_this.getMoveType = function (move) {
var moveStats = null;
if (move !== null) {
moveStats = _this.props.movesById.get(move.id) || null;
}
if (moveStats !== null) {
return moveStats.type;
}
return null;
}; };
_this.handleToggleQuickMoveMenu = function (isOpen) { _this.handleToggleQuickMoveMenu = function (isOpen) {
@ -38573,17 +38543,18 @@ function (_react_1$default$Comp) {
movesById = _this$props2.movesById, movesById = _this$props2.movesById,
quickMoves = _this$props2.quickMoves, quickMoves = _this$props2.quickMoves,
chargeMoves = _this$props2.chargeMoves, chargeMoves = _this$props2.chargeMoves,
combatMoveSelectorsOpen = _this$props2.combatMoveSelectorsOpen; combatMoveSelectorsOpen = _this$props2.combatMoveSelectorsOpen,
pokemonTypeWeaknesses = _this$props2.pokemonTypeWeaknesses;
var _this$props$selectedM = this.props.selectedMoves, var _this$props$selectedM = this.props.selectedMoves,
quickMove = _this$props$selectedM.quickMove, quickMove = _this$props$selectedM.quickMove,
chargeMove1 = _this$props$selectedM.chargeMove1, chargeMove1 = _this$props$selectedM.chargeMove1,
chargeMove2 = _this$props$selectedM.chargeMove2; chargeMove2 = _this$props$selectedM.chargeMove2;
var wrapperCss = classnames_1.default('nes-container', styles.wrapper); var wrapperCss = classnames_1.default('nes-container', styles.wrapper);
var quickMoveType = this.getMoveType(quickMove); var quickMoveType = types_1.getMoveType(quickMove, movesById);
var quickMoveCss = classnames_1.default(_defineProperty({}, styles.legacy, quickMove ? quickMove.isLegacy : false)); var quickMoveCss = classnames_1.default(_defineProperty({}, styles.legacy, quickMove ? quickMove.isLegacy : false));
var chargeMove1Type = this.getMoveType(chargeMove1); var chargeMove1Type = types_1.getMoveType(chargeMove1, movesById);
var chargeMove1Css = classnames_1.default(_defineProperty({}, styles.legacy, chargeMove1 ? chargeMove1.isLegacy : false)); var chargeMove1Css = classnames_1.default(_defineProperty({}, styles.legacy, chargeMove1 ? chargeMove1.isLegacy : false));
var chargeMove2Type = this.getMoveType(chargeMove2); var chargeMove2Type = types_1.getMoveType(chargeMove2, movesById);
var chargeMove2Css = classnames_1.default(_defineProperty({}, styles.legacy, chargeMove2 ? chargeMove2.isLegacy : false)); var chargeMove2Css = classnames_1.default(_defineProperty({}, styles.legacy, chargeMove2 ? chargeMove2.isLegacy : false));
return react_1.default.createElement("div", { return react_1.default.createElement("div", {
className: wrapperCss className: wrapperCss
@ -38597,7 +38568,8 @@ function (_react_1$default$Comp) {
handleChangeSelectedOption: this.handleChangeQuickMove handleChangeSelectedOption: this.handleChangeQuickMove
}), quickMove && quickMoveType && react_1.default.createElement(TypeIndicator_1.TypeIndicator, { }), quickMove && quickMoveType && react_1.default.createElement(TypeIndicator_1.TypeIndicator, {
className: quickMoveCss, className: quickMoveCss,
type: quickMoveType type: quickMoveType,
theme: TypeIndicator_1.TypeTheme.SOLID
}), react_1.default.createElement(MovesDropdown_1.MovesDropdown, { }), react_1.default.createElement(MovesDropdown_1.MovesDropdown, {
isMenuOpen: combatMoveSelectorsOpen.chargeMove1, isMenuOpen: combatMoveSelectorsOpen.chargeMove1,
menuLabel: "Charge Move 1", menuLabel: "Charge Move 1",
@ -38608,7 +38580,8 @@ function (_react_1$default$Comp) {
handleChangeSelectedOption: this.handleChangeChargeMove1 handleChangeSelectedOption: this.handleChangeChargeMove1
}), chargeMove1 && chargeMove1Type && react_1.default.createElement(TypeIndicator_1.TypeIndicator, { }), chargeMove1 && chargeMove1Type && react_1.default.createElement(TypeIndicator_1.TypeIndicator, {
className: chargeMove1Css, className: chargeMove1Css,
type: chargeMove1Type type: chargeMove1Type,
theme: TypeIndicator_1.TypeTheme.SOLID
}), react_1.default.createElement(MovesDropdown_1.MovesDropdown, { }), react_1.default.createElement(MovesDropdown_1.MovesDropdown, {
isMenuOpen: combatMoveSelectorsOpen.chargeMove2, isMenuOpen: combatMoveSelectorsOpen.chargeMove2,
menuLabel: "Charge Move 2", menuLabel: "Charge Move 2",
@ -38619,10 +38592,12 @@ function (_react_1$default$Comp) {
handleChangeSelectedOption: this.handleChangeChargeMove2 handleChangeSelectedOption: this.handleChangeChargeMove2
}), chargeMove2 && chargeMove2Type && react_1.default.createElement(TypeIndicator_1.TypeIndicator, { }), chargeMove2 && chargeMove2Type && react_1.default.createElement(TypeIndicator_1.TypeIndicator, {
className: chargeMove2Css, className: chargeMove2Css,
type: chargeMove2Type type: chargeMove2Type,
theme: TypeIndicator_1.TypeTheme.SOLID
}), react_1.default.createElement("div", null, react_1.default.createElement("h4", null, "Type Coverage"), react_1.default.createElement(TypeEffectiveDisplay_1.TypeEffectiveDisplay, { }), react_1.default.createElement("div", null, react_1.default.createElement("h4", null, "Type Coverage"), react_1.default.createElement(TypeEffectiveDisplay_1.TypeEffectiveDisplay, {
pokemonName: "test", mode: TypeEffectiveDisplay_1.EffectivenessMode.OFFENSE,
effectiveness: this.calculateTypeCoverage() effectiveness: this.calculateTypeCoverage(),
coverage: pokemonTypeWeaknesses
}))); })));
} }
}]); }]);
@ -38764,13 +38739,15 @@ function (_react_1$default$Comp) {
fairy: formatter_1.Forms.fairy.indexOf(leaguePokemon.form) > -1 fairy: formatter_1.Forms.fairy.indexOf(leaguePokemon.form) > -1
}); });
var type1 = react_1.default.createElement(TypeIndicator_1.TypeIndicator, { var type1 = react_1.default.createElement(TypeIndicator_1.TypeIndicator, {
type: leaguePokemon.types.type1 type: leaguePokemon.types.type1,
theme: TypeIndicator_1.TypeTheme.SOLID
}); });
var type2 = null; var type2 = null;
if (leaguePokemon.types.type2) { if (leaguePokemon.types.type2) {
type2 = react_1.default.createElement(TypeIndicator_1.TypeIndicator, { type2 = react_1.default.createElement(TypeIndicator_1.TypeIndicator, {
type: leaguePokemon.types.type2 type: leaguePokemon.types.type2,
theme: TypeIndicator_1.TypeTheme.SOLID
}); });
} }
@ -38874,6 +38851,8 @@ var react_redux_1 = __webpack_require__(/*! react-redux */ "./node_modules/react
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 Pokemon_1 = __webpack_require__(/*! app/models/Pokemon */ "./src/ts/app/models/Pokemon.ts");
var ActionsPokemonExplorer = __importStar(__webpack_require__(/*! app/components/PokemonExplorer/actions */ "./src/ts/app/components/PokemonExplorer/actions.ts")); var ActionsPokemonExplorer = __importStar(__webpack_require__(/*! app/components/PokemonExplorer/actions */ "./src/ts/app/components/PokemonExplorer/actions.ts"));
var LeagueIvExplorer_1 = __webpack_require__(/*! app/components/PokemonExplorer/LeagueIvExplorer */ "./src/ts/app/components/PokemonExplorer/LeagueIvExplorer.tsx"); var LeagueIvExplorer_1 = __webpack_require__(/*! app/components/PokemonExplorer/LeagueIvExplorer */ "./src/ts/app/components/PokemonExplorer/LeagueIvExplorer.tsx");
@ -38886,6 +38865,8 @@ var TypeEffectiveDisplay_1 = __webpack_require__(/*! app/components/PokemonExplo
var navigation_1 = __webpack_require__(/*! app/utils/navigation */ "./src/ts/app/utils/navigation.ts"); var navigation_1 = __webpack_require__(/*! app/utils/navigation */ "./src/ts/app/utils/navigation.ts");
var types_1 = __webpack_require__(/*! app/utils/types */ "./src/ts/app/utils/types.ts");
var styles = __importStar(__webpack_require__(/*! app/styles/PokemonApp.scss */ "./src/ts/app/styles/PokemonApp.scss")); var styles = __importStar(__webpack_require__(/*! app/styles/PokemonApp.scss */ "./src/ts/app/styles/PokemonApp.scss"));
var PokemonExplorer = var PokemonExplorer =
@ -38900,6 +38881,18 @@ function (_react_1$default$Comp) {
_this = _possibleConstructorReturn(this, _getPrototypeOf(PokemonExplorer).call(this, props)); _this = _possibleConstructorReturn(this, _getPrototypeOf(PokemonExplorer).call(this, props));
_this.getSuperEffectiveTypes = function (effectiveness) {
var superEffectiveTypes = [];
Array.from(effectiveness).reduce(function (accumulator, currentValue) {
if (currentValue[1] > Pokemon_1.TypeEffectiveness.NEUTRAL) {
accumulator.push(currentValue[0]);
}
return accumulator;
}, superEffectiveTypes);
return superEffectiveTypes;
};
_this.handleToggleDropdownOpen = function (menu, isOpen) { _this.handleToggleDropdownOpen = function (menu, isOpen) {
var combatMoveSelectorsOpen = Object.assign({}, _this.props.pokemonExplorerState.combatMoveSelectorsOpen, _defineProperty({}, menu, isOpen)); var combatMoveSelectorsOpen = Object.assign({}, _this.props.pokemonExplorerState.combatMoveSelectorsOpen, _defineProperty({}, menu, isOpen));
@ -39037,7 +39030,11 @@ function (_react_1$default$Comp) {
var tmCss = classnames_1.default(iconCss, 'tm', { var tmCss = classnames_1.default(iconCss, 'tm', {
active: widgets.moves active: widgets.moves
}); });
var tmButtonCss = classnames_1.default(); var tmButtonCss = classnames_1.default(); // weaknesses are indicated by types that cause super effective damage on defense
var pokemonTypeWeaknesses = leaguePokemon !== null ? this.getSuperEffectiveTypes(leaguePokemon.effectiveness) : []; // strengths are indicuated by types that do super effective damage on offense
var moveTypeStrengths = this.getSuperEffectiveTypes(types_1.calculateTypeCoverage(selectedCombatMoves, combatMoves, attackTypeEffectiveness));
return react_1.default.createElement("div", { return react_1.default.createElement("div", {
className: styles.body className: styles.body
}, react_1.default.createElement("div", { }, react_1.default.createElement("div", {
@ -39045,10 +39042,13 @@ function (_react_1$default$Comp) {
}, leaguePokemon !== null && react_1.default.createElement(PokemonDisplay_1.PokemonDisplay, { }, leaguePokemon !== null && react_1.default.createElement(PokemonDisplay_1.PokemonDisplay, {
leaguePokemon: leaguePokemon, leaguePokemon: leaguePokemon,
isHighlighted: isOverlayShown isHighlighted: isOverlayShown
}), widgets.types && leaguePokemon !== null && react_1.default.createElement(TypeEffectiveDisplay_1.TypeEffectiveDisplay, { }), widgets.types && leaguePokemon !== null && react_1.default.createElement("div", {
className: "nes-container"
}, react_1.default.createElement(TypeEffectiveDisplay_1.TypeEffectiveDisplay, {
mode: TypeEffectiveDisplay_1.EffectivenessMode.DEFENSE,
effectiveness: leaguePokemon.effectiveness, effectiveness: leaguePokemon.effectiveness,
pokemonName: leaguePokemon.name coverage: moveTypeStrengths
}), widgets.pvp && leaguePokemon !== null && react_1.default.createElement(LeagueIvExplorer_1.LeagueIvExplorer, { })), widgets.pvp && leaguePokemon !== null && react_1.default.createElement(LeagueIvExplorer_1.LeagueIvExplorer, {
activeLeague: league, activeLeague: league,
leaguePokemon: leaguePokemon, leaguePokemon: leaguePokemon,
individualValues: individualValues, individualValues: individualValues,
@ -39060,6 +39060,7 @@ function (_react_1$default$Comp) {
quickMoves: leaguePokemon.moves.quick, quickMoves: leaguePokemon.moves.quick,
chargeMoves: leaguePokemon.moves.cinematic, chargeMoves: leaguePokemon.moves.cinematic,
selectedMoves: selectedCombatMoves, selectedMoves: selectedCombatMoves,
pokemonTypeWeaknesses: pokemonTypeWeaknesses,
attackTypeEffectiveness: attackTypeEffectiveness, attackTypeEffectiveness: attackTypeEffectiveness,
combatMoveSelectorsOpen: combatMoveSelectorsOpen, combatMoveSelectorsOpen: combatMoveSelectorsOpen,
handleToggleDropdownOpen: this.handleToggleDropdownOpen, handleToggleDropdownOpen: this.handleToggleDropdownOpen,
@ -39281,72 +39282,125 @@ var TypeIndicator_1 = __webpack_require__(/*! ./TypeIndicator */ "./src/ts/app/c
var styles = __importStar(__webpack_require__(/*! app/components/PokemonExplorer/styles/TypeEffectiveDisplay.scss */ "./src/ts/app/components/PokemonExplorer/styles/TypeEffectiveDisplay.scss")); var styles = __importStar(__webpack_require__(/*! app/components/PokemonExplorer/styles/TypeEffectiveDisplay.scss */ "./src/ts/app/components/PokemonExplorer/styles/TypeEffectiveDisplay.scss"));
var EffectivenessMode;
(function (EffectivenessMode) {
EffectivenessMode[EffectivenessMode["OFFENSE"] = 0] = "OFFENSE";
EffectivenessMode[EffectivenessMode["DEFENSE"] = 1] = "DEFENSE";
})(EffectivenessMode = exports.EffectivenessMode || (exports.EffectivenessMode = {}));
var TypeEffectiveDisplay = var TypeEffectiveDisplay =
/*#__PURE__*/ /*#__PURE__*/
function (_react_1$default$Comp) { function (_react_1$default$Comp) {
_inherits(TypeEffectiveDisplay, _react_1$default$Comp); _inherits(TypeEffectiveDisplay, _react_1$default$Comp);
function TypeEffectiveDisplay() { function TypeEffectiveDisplay() {
var _this;
_classCallCheck(this, TypeEffectiveDisplay); _classCallCheck(this, TypeEffectiveDisplay);
return _possibleConstructorReturn(this, _getPrototypeOf(TypeEffectiveDisplay).apply(this, arguments)); _this = _possibleConstructorReturn(this, _getPrototypeOf(TypeEffectiveDisplay).apply(this, arguments));
_this.isTypeCovered = function (type) {
return _this.props.coverage.some(function (coverageType) {
return coverageType === type;
});
};
return _this;
} }
_createClass(TypeEffectiveDisplay, [{ _createClass(TypeEffectiveDisplay, [{
key: "render", key: "render",
value: function render() { value: function render() {
var _this2 = this;
var _this$props = this.props, var _this$props = this.props,
effectiveness = _this$props.effectiveness, mode = _this$props.mode,
pokemonName = _this$props.pokemonName; effectiveness = _this$props.effectiveness;
var wrapperCss = classnames_1.default('nes-container', styles.wrapper); var wrapperCss = classnames_1.default('nes-container', styles.wrapper);
var indicatorWrapperCss = classnames_1.default(styles.indicatorWrapper); var indicatorWrapperCss = classnames_1.default(styles.indicatorWrapper);
var multiplierWrapperX2Css = classnames_1.default(styles.multiplierWrapper); var multiplierWrapperX2Css = classnames_1.default(styles.typeMultiplierWrapper);
var multiplierWrapperX3Css = classnames_1.default(styles.multiplierWrapper, styles.multiplierWrapperX3); var multiplierWrapperX3Css = classnames_1.default(styles.typeMultiplierWrapper, styles.typeMultiplierWrapperX3);
var multiplierWrapperX4Css = classnames_1.default(styles.multiplierWrapper, styles.multiplierWrapperX4); var multiplierWrapperX4Css = classnames_1.default(styles.typeMultiplierWrapper, styles.typeMultiplierWrapperX4);
var superEffectiveX2 = []; var superEffectiveX2 = [];
var superEffective = []; var superEffective = [];
var notVeryEffective = []; var notVeryEffective = [];
var notVeryEffectiveX2 = []; var notVeryEffectiveX2 = [];
var notVeryEffectiveX3 = []; var notVeryEffectiveX3 = [];
var notVeryEffectiveX4 = []; var notVeryEffectiveX4 = [];
var supereffectiveCoverage = [];
var supereffectiveCoverageX2 = [];
var notVeryEffectiveCoverage = [];
var notVeryEffectiveCoverageX2 = [];
var notVeryEffectiveCoverageX3 = [];
var notVeryEffectiveCoverageX4 = [];
effectiveness.forEach(function (value, key) { effectiveness.forEach(function (value, key) {
var typeIndicator;
if (value === Pokemon_1.TypeEffectiveness.SUPER_EFFECTIVE || value === Pokemon_1.TypeEffectiveness.NOT_VERY_EFFECTIVE) {
// using `key` because these are later transformed into an array of duplicate elements
typeIndicator = react_1.default.createElement(TypeIndicator_1.TypeIndicator, {
key: key,
type: key
});
} else {
typeIndicator = react_1.default.createElement(TypeIndicator_1.TypeIndicator, {
type: key
});
}
switch (value) { switch (value) {
case Pokemon_1.TypeEffectiveness.SUPER_EFFECTIVE_X2: case Pokemon_1.TypeEffectiveness.SUPER_EFFECTIVE_X2:
superEffectiveX2.push(typeIndicator); superEffectiveX2.push(react_1.default.createElement(TypeIndicator_1.TypeIndicator, {
type: key,
theme: TypeIndicator_1.TypeTheme.SOLID
}));
supereffectiveCoverageX2.push(_this2.isTypeCovered(key));
break; break;
case Pokemon_1.TypeEffectiveness.SUPER_EFFECTIVE: case Pokemon_1.TypeEffectiveness.SUPER_EFFECTIVE:
superEffective.push(typeIndicator); superEffective.push(react_1.default.createElement(TypeIndicator_1.TypeIndicator, {
key: key,
type: key,
theme: TypeIndicator_1.TypeTheme.SOLID
}));
supereffectiveCoverage.push(_this2.isTypeCovered(key));
break; break;
case Pokemon_1.TypeEffectiveness.NOT_VERY_EFFECTIVE: case Pokemon_1.TypeEffectiveness.NOT_VERY_EFFECTIVE:
notVeryEffective.push(typeIndicator); notVeryEffective.push(react_1.default.createElement(TypeIndicator_1.TypeIndicator, {
key: key,
type: key,
theme: TypeIndicator_1.TypeTheme.OUTLINE
}));
if (mode === EffectivenessMode.DEFENSE) {
notVeryEffectiveCoverage.push(_this2.isTypeCovered(key));
}
break; break;
case Pokemon_1.TypeEffectiveness.IMMUNE: case Pokemon_1.TypeEffectiveness.IMMUNE:
notVeryEffectiveX2.push(typeIndicator); notVeryEffectiveX2.push(react_1.default.createElement(TypeIndicator_1.TypeIndicator, {
type: key,
theme: TypeIndicator_1.TypeTheme.OUTLINE
}));
if (mode === EffectivenessMode.DEFENSE) {
notVeryEffectiveCoverageX2.push(_this2.isTypeCovered(key));
}
break; break;
case Pokemon_1.TypeEffectiveness.NOT_VERY_EFFECTIVE_X3: case Pokemon_1.TypeEffectiveness.NOT_VERY_EFFECTIVE_X3:
notVeryEffectiveX3.push(typeIndicator); notVeryEffectiveX3.push(react_1.default.createElement(TypeIndicator_1.TypeIndicator, {
type: key,
theme: TypeIndicator_1.TypeTheme.OUTLINE
}));
if (mode === EffectivenessMode.DEFENSE) {
notVeryEffectiveCoverageX3.push(_this2.isTypeCovered(key));
}
break; break;
case Pokemon_1.TypeEffectiveness.IMMUNE_X2: case Pokemon_1.TypeEffectiveness.IMMUNE_X2:
notVeryEffectiveX4.push(typeIndicator); notVeryEffectiveX4.push(react_1.default.createElement(TypeIndicator_1.TypeIndicator, {
type: key,
theme: TypeIndicator_1.TypeTheme.OUTLINE
}));
if (mode === EffectivenessMode.DEFENSE) {
notVeryEffectiveCoverageX4.push(_this2.isTypeCovered(key));
}
break; break;
case Pokemon_1.TypeEffectiveness.NEUTRAL: case Pokemon_1.TypeEffectiveness.NEUTRAL:
@ -39360,31 +39414,41 @@ function (_react_1$default$Comp) {
}); });
return react_1.default.createElement("div", { return react_1.default.createElement("div", {
className: wrapperCss className: wrapperCss
}, (notVeryEffective.length > 0 || notVeryEffectiveX2.length > 0 || notVeryEffectiveX3.length > 0 || notVeryEffectiveX4.length > 0) && react_1.default.createElement(react_1.default.Fragment, null, react_1.default.createElement("h4", null, pokemonName, "'s Resistances", react_1.default.createElement("p", null, "It's Not Very Effective...")), react_1.default.createElement("div", { }, (notVeryEffective.length > 0 || notVeryEffectiveX2.length > 0 || notVeryEffectiveX3.length > 0 || notVeryEffectiveX4.length > 0) && react_1.default.createElement(react_1.default.Fragment, null, react_1.default.createElement("h4", null, mode === EffectivenessMode.DEFENSE ? 'Resistances' : "It's not very effective..."), react_1.default.createElement("div", {
className: indicatorWrapperCss className: indicatorWrapperCss
}, notVeryEffectiveX4.length > 0 && notVeryEffectiveX4.map(function (element, index) { }, notVeryEffectiveX4.length > 0 && notVeryEffectiveX4.map(function (element, index) {
return react_1.default.createElement("div", { return react_1.default.createElement("div", {
key: "-4x".concat(index), key: "-4x".concat(index),
className: multiplierWrapperX4Css className: "".concat(multiplierWrapperX4Css, " ").concat(notVeryEffectiveCoverageX4[index] ? styles.isCovered : '')
}, element, element, element, element); }, element, element, element, element);
}), notVeryEffectiveX3.length > 0 && notVeryEffectiveX3.map(function (element, index) { }), notVeryEffectiveX3.length > 0 && notVeryEffectiveX3.map(function (element, index) {
return react_1.default.createElement("div", { return react_1.default.createElement("div", {
key: "-3x".concat(index), key: "-3x".concat(index),
className: multiplierWrapperX3Css className: "".concat(multiplierWrapperX3Css, " ").concat(notVeryEffectiveCoverageX2[index] ? styles.isCovered : '')
}, element, element, element); }, element, element, element);
}), notVeryEffectiveX2.length > 0 && notVeryEffectiveX2.map(function (element, index) { }), notVeryEffectiveX2.length > 0 && notVeryEffectiveX2.map(function (element, index) {
return react_1.default.createElement("div", { return react_1.default.createElement("div", {
key: "-2x".concat(index), key: "-2x".concat(index),
className: multiplierWrapperX2Css className: "".concat(multiplierWrapperX2Css, " ").concat(notVeryEffectiveCoverageX2[index] ? styles.isCovered : '')
}, element, element); }, element, element);
}), notVeryEffective.length > 0 && notVeryEffective)), (superEffective.length > 0 || superEffectiveX2.length > 0) && react_1.default.createElement(react_1.default.Fragment, null, react_1.default.createElement("h4", null, pokemonName, "'s Weaknesses", react_1.default.createElement("p", null, "It's Super Effective!")), react_1.default.createElement("div", { }), notVeryEffective.length > 0 && notVeryEffective.map(function (element, index) {
return react_1.default.createElement("div", {
key: index,
className: "".concat(styles.typeWrapper, " ").concat(notVeryEffectiveCoverage[index] ? styles.isCovered : '')
}, element);
}))), (superEffective.length > 0 || superEffectiveX2.length > 0) && react_1.default.createElement(react_1.default.Fragment, null, react_1.default.createElement("h4", null, mode === EffectivenessMode.DEFENSE ? 'Weaknesses' : "It's super effective!"), react_1.default.createElement("div", {
className: indicatorWrapperCss className: indicatorWrapperCss
}, superEffectiveX2.length > 0 && superEffectiveX2.map(function (element, index) { }, superEffectiveX2.length > 0 && superEffectiveX2.map(function (element, index) {
return react_1.default.createElement("div", { return react_1.default.createElement("div", {
key: "+2x".concat(index), key: "+2x".concat(index),
className: multiplierWrapperX2Css className: "".concat(multiplierWrapperX2Css, " ").concat(supereffectiveCoverageX2[index] ? styles.isCovered : '')
}, element, element); }, element, element);
}), superEffective.length > 0 && superEffective))); }), superEffective.length > 0 && superEffective.map(function (element, index) {
return react_1.default.createElement("div", {
key: index,
className: "".concat(styles.typeWrapper, " ").concat(supereffectiveCoverage[index] ? styles.isCovered : '')
}, element);
}))));
} }
}]); }]);
@ -39452,6 +39516,13 @@ var formatter_1 = __webpack_require__(/*! app/utils/formatter */ "./src/ts/app/u
var styles = __importStar(__webpack_require__(/*! app/components/PokemonExplorer/styles/TypeIndicator.scss */ "./src/ts/app/components/PokemonExplorer/styles/TypeIndicator.scss")); var styles = __importStar(__webpack_require__(/*! app/components/PokemonExplorer/styles/TypeIndicator.scss */ "./src/ts/app/components/PokemonExplorer/styles/TypeIndicator.scss"));
var TypeTheme;
(function (TypeTheme) {
TypeTheme[TypeTheme["SOLID"] = 0] = "SOLID";
TypeTheme[TypeTheme["OUTLINE"] = 1] = "OUTLINE";
})(TypeTheme = exports.TypeTheme || (exports.TypeTheme = {}));
var TypeIndicator = var TypeIndicator =
/*#__PURE__*/ /*#__PURE__*/
function (_react_1$default$Comp) { function (_react_1$default$Comp) {
@ -39468,10 +39539,12 @@ function (_react_1$default$Comp) {
value: function render() { value: function render() {
var _this$props = this.props, var _this$props = this.props,
className = _this$props.className, className = _this$props.className,
theme = _this$props.theme,
type = _this$props.type; type = _this$props.type;
var containerCss = classnames_1.default('nes-container', 'with-title'); var containerCss = classnames_1.default('nes-container', 'with-title', 'is-rounded');
var containerRoundCss = classnames_1.default(containerCss, 'is-rounded'); var pokemonTypeCss = classnames_1.default(className, containerCss, styles.pokemonType, {
var pokemonTypeCss = classnames_1.default(className, containerRoundCss, styles.pokemonType); outline: theme === TypeTheme.OUTLINE
});
return react_1.default.createElement("div", { return react_1.default.createElement("div", {
className: "".concat(pokemonTypeCss, " ").concat(formatter_1.formatType(type)) className: "".concat(pokemonTypeCss, " ").concat(formatter_1.formatType(type))
}, formatter_1.formatType(type)); }, formatter_1.formatType(type));
@ -39890,7 +39963,7 @@ module.exports = {"baseStatRow":"StatDisplay__baseStatRow__1B60A"};
/***/ (function(module, exports, __webpack_require__) { /***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin // extracted by mini-css-extract-plugin
module.exports = {"multiplierWrapper":"TypeEffectiveDisplay__multiplierWrapper__14os7","multiplierWrapperX3":"TypeEffectiveDisplay__multiplierWrapperX3__1SBG1","multiplierWrapperX4":"TypeEffectiveDisplay__multiplierWrapperX4__2KqYa","wrapper":"TypeEffectiveDisplay__wrapper__1FFIj","indicatorWrapper":"TypeEffectiveDisplay__indicatorWrapper__2F3AY"}; module.exports = {"typeWrapper":"TypeEffectiveDisplay__typeWrapper__3w4wT","typeMultiplierWrapper":"TypeEffectiveDisplay__typeMultiplierWrapper__1WOCi","typeMultiplierWrapperX3":"TypeEffectiveDisplay__typeMultiplierWrapperX3__35-RS","typeMultiplierWrapperX4":"TypeEffectiveDisplay__typeMultiplierWrapperX4__2Onf7","wrapper":"TypeEffectiveDisplay__wrapper__1FFIj","indicatorWrapper":"TypeEffectiveDisplay__indicatorWrapper__2F3AY","isCovered":"TypeEffectiveDisplay__isCovered__3qyUq"};
/***/ }), /***/ }),
@ -41180,6 +41253,59 @@ exports.appendQueryString = function (location, parameters) {
return '?' + search.toString(); return '?' + search.toString();
}; };
/***/ }),
/***/ "./src/ts/app/utils/types.ts":
/*!***********************************!*\
!*** ./src/ts/app/utils/types.ts ***!
\***********************************/
/*! no static exports found */
/*! ModuleConcatenation bailout: Module is not an ECMAScript module */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.calculateTypeCoverage = function (selectedMoves, movesById, attackTypeEffectiveness) {
var calculatedffectiveness = new Map();
Object.values(selectedMoves).forEach(function (move) {
var moveType = exports.getMoveType(move, movesById);
if (moveType !== null) {
var moveEffectiveness = attackTypeEffectiveness.get(moveType);
if (typeof moveEffectiveness !== 'undefined') {
moveEffectiveness.forEach(function (effectiveness, type) {
var currentEffectiveness = calculatedffectiveness.get(type);
if (typeof currentEffectiveness === 'undefined' || effectiveness > currentEffectiveness) {
calculatedffectiveness.set(type, effectiveness);
}
});
}
}
});
return calculatedffectiveness;
};
exports.getMoveType = function (move, movesById) {
var moveStats = null;
if (move !== null) {
moveStats = movesById.get(move.id) || null;
}
if (moveStats !== null) {
return moveStats.type;
}
return null;
};
/***/ }) /***/ })
/******/ }); /******/ });

View File

@ -1,4 +1,5 @@
@import '~nes.css/scss/base/color-palette'; @import '~nes.css/scss/base/color-palette';
@import '~nes.css/scss/base/variables';
$container-width: ( $container-width: (
desktop: 425px, desktop: 425px,
@ -51,6 +52,7 @@ $main-active-font-color: $gray-scale-1;
$main-border-color: $gray-scale-4; $main-border-color: $gray-scale-4;
$main-overlay-color: $gray-scale-4; $main-overlay-color: $gray-scale-4;
$main-hover-color: darken($main-background-color, 5%); $main-hover-color: darken($main-background-color, 5%);
$main-success: map-get($success-colors, 'normal');
$great-league-colors: ( $great-league-colors: (
primary: #649bde, primary: #649bde,

View File

@ -6,7 +6,7 @@ import classNames from 'classnames';
import { CombatMoveStats, IPokemonMove } from 'app/models/Pokemon'; import { CombatMoveStats, IPokemonMove } from 'app/models/Pokemon';
import { TypeIndicator } from './TypeIndicator'; import { TypeIndicator, TypeTheme } from './TypeIndicator';
import * as styles from 'app/components/PokemonExplorer/styles/MovesDropdown.scss'; import * as styles from 'app/components/PokemonExplorer/styles/MovesDropdown.scss';
@ -174,7 +174,7 @@ export class MovesDropdown extends React.Component<IMovesDropdownProps, IState>
onClick={ onClick } onClick={ onClick }
> >
<span>{ moveStats.name }</span> <span>{ moveStats.name }</span>
<TypeIndicator className={ typeCss } type={ moveStats.type } /> <TypeIndicator className={ typeCss } type={ moveStats.type } theme={ TypeTheme.SOLID }/>
</a> </a>
} }
</React.Fragment> </React.Fragment>

View File

@ -5,13 +5,15 @@ import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { AttackTypeEffectiveness } from 'app/models/Config'; import { AttackTypeEffectiveness } from 'app/models/Config';
import { CombatMoveStats, ICombatMoveStats, IPokemonMove, TypeEffectiveness } from 'app/models/Pokemon'; import { CombatMoveStats, IPokemon, IPokemonMove } from 'app/models/Pokemon';
import { CombatMoveSelectorsOpen, SelectedCombatMoves } from 'app/components/PokemonExplorer/types'; import { CombatMoveSelectorsOpen, SelectedCombatMoves } from 'app/components/PokemonExplorer/types';
import { MovesDropdown } from 'app/components/PokemonExplorer/MovesDropdown'; import { MovesDropdown } from 'app/components/PokemonExplorer/MovesDropdown';
import { TypeEffectiveDisplay } from './TypeEffectiveDisplay'; import { EffectivenessMode, TypeEffectiveDisplay } from './TypeEffectiveDisplay';
import { TypeIndicator } from './TypeIndicator'; import { TypeIndicator, TypeTheme } from './TypeIndicator';
import { calculateTypeCoverage, getMoveType } from 'app/utils/types';
import * as styles from 'app/components/PokemonExplorer/styles/MovesExplorer.scss'; import * as styles from 'app/components/PokemonExplorer/styles/MovesExplorer.scss';
@ -20,6 +22,7 @@ export interface IMovesExplorerProps {
quickMoves : Array<IPokemonMove>; quickMoves : Array<IPokemonMove>;
chargeMoves : Array<IPokemonMove>; chargeMoves : Array<IPokemonMove>;
selectedMoves : SelectedCombatMoves; selectedMoves : SelectedCombatMoves;
pokemonTypeWeaknesses : Array<POGOProtos.Enums.PokemonType>;
attackTypeEffectiveness : AttackTypeEffectiveness; attackTypeEffectiveness : AttackTypeEffectiveness;
combatMoveSelectorsOpen : CombatMoveSelectorsOpen; combatMoveSelectorsOpen : CombatMoveSelectorsOpen;
handleToggleDropdownOpen : (menu : keyof CombatMoveSelectorsOpen, isOpen : boolean) => void; handleToggleDropdownOpen : (menu : keyof CombatMoveSelectorsOpen, isOpen : boolean) => void;
@ -34,6 +37,7 @@ export class MovesExplorer extends React.Component<IMovesExplorerProps> {
quickMoves, quickMoves,
chargeMoves, chargeMoves,
combatMoveSelectorsOpen, combatMoveSelectorsOpen,
pokemonTypeWeaknesses,
} = this.props; } = this.props;
const { const {
quickMove, quickMove,
@ -46,15 +50,15 @@ export class MovesExplorer extends React.Component<IMovesExplorerProps> {
styles.wrapper, styles.wrapper,
); );
const quickMoveType = this.getMoveType(quickMove); const quickMoveType = getMoveType(quickMove, movesById);
const quickMoveCss = classNames({ const quickMoveCss = classNames({
[styles.legacy]: quickMove ? quickMove.isLegacy : false, [styles.legacy]: quickMove ? quickMove.isLegacy : false,
}); });
const chargeMove1Type = this.getMoveType(chargeMove1); const chargeMove1Type = getMoveType(chargeMove1, movesById);
const chargeMove1Css = classNames({ const chargeMove1Css = classNames({
[styles.legacy]: chargeMove1 ? chargeMove1.isLegacy : false, [styles.legacy]: chargeMove1 ? chargeMove1.isLegacy : false,
}); });
const chargeMove2Type = this.getMoveType(chargeMove2); const chargeMove2Type = getMoveType(chargeMove2, movesById);
const chargeMove2Css = classNames({ const chargeMove2Css = classNames({
[styles.legacy]: chargeMove2 ? chargeMove2.isLegacy : false, [styles.legacy]: chargeMove2 ? chargeMove2.isLegacy : false,
}); });
@ -71,7 +75,7 @@ export class MovesExplorer extends React.Component<IMovesExplorerProps> {
handleChangeSelectedOption={ this.handleChangeQuickMove } handleChangeSelectedOption={ this.handleChangeQuickMove }
/> />
{ quickMove && quickMoveType && { quickMove && quickMoveType &&
<TypeIndicator className={ quickMoveCss } type={ quickMoveType } /> <TypeIndicator className={ quickMoveCss } type={ quickMoveType } theme={ TypeTheme.SOLID }/>
} }
<MovesDropdown <MovesDropdown
isMenuOpen={ combatMoveSelectorsOpen.chargeMove1 } isMenuOpen={ combatMoveSelectorsOpen.chargeMove1 }
@ -83,7 +87,7 @@ export class MovesExplorer extends React.Component<IMovesExplorerProps> {
handleChangeSelectedOption={ this.handleChangeChargeMove1 } handleChangeSelectedOption={ this.handleChangeChargeMove1 }
/> />
{ chargeMove1 && chargeMove1Type && { chargeMove1 && chargeMove1Type &&
<TypeIndicator className={ chargeMove1Css } type={ chargeMove1Type } /> <TypeIndicator className={ chargeMove1Css } type={ chargeMove1Type } theme={ TypeTheme.SOLID }/>
} }
<MovesDropdown <MovesDropdown
isMenuOpen={ combatMoveSelectorsOpen.chargeMove2 } isMenuOpen={ combatMoveSelectorsOpen.chargeMove2 }
@ -95,13 +99,14 @@ export class MovesExplorer extends React.Component<IMovesExplorerProps> {
handleChangeSelectedOption={ this.handleChangeChargeMove2 } handleChangeSelectedOption={ this.handleChangeChargeMove2 }
/> />
{ chargeMove2 && chargeMove2Type && { chargeMove2 && chargeMove2Type &&
<TypeIndicator className={ chargeMove2Css } type={ chargeMove2Type } /> <TypeIndicator className={ chargeMove2Css } type={ chargeMove2Type } theme={ TypeTheme.SOLID }/>
} }
<div> <div>
<h4>Type Coverage</h4> <h4>Type Coverage</h4>
<TypeEffectiveDisplay <TypeEffectiveDisplay
pokemonName="test" mode={ EffectivenessMode.OFFENSE }
effectiveness={ this.calculateTypeCoverage() } effectiveness={ this.calculateTypeCoverage() }
coverage={ pokemonTypeWeaknesses }
/> />
</div> </div>
</div> </div>
@ -111,36 +116,10 @@ export class MovesExplorer extends React.Component<IMovesExplorerProps> {
private readonly calculateTypeCoverage = () => { private readonly calculateTypeCoverage = () => {
const { const {
selectedMoves, selectedMoves,
movesById,
attackTypeEffectiveness, attackTypeEffectiveness,
} = this.props; } = this.props;
const calculatedffectiveness : Map<POGOProtos.Enums.PokemonType, TypeEffectiveness> = new Map(); return calculateTypeCoverage(selectedMoves, movesById, attackTypeEffectiveness);
Object.values(selectedMoves).forEach((move) => {
const moveType = this.getMoveType(move);
if (moveType !== null) {
const moveEffectiveness = attackTypeEffectiveness.get(moveType);
if (typeof moveEffectiveness !== 'undefined') {
moveEffectiveness.forEach((effectiveness, type) => {
const currentEffectiveness = calculatedffectiveness.get(type);
if (typeof currentEffectiveness === 'undefined' || TypeEffectiveness[effectiveness] > TypeEffectiveness[currentEffectiveness]) {
calculatedffectiveness.set(type, effectiveness);
}
});
}
}
});
return calculatedffectiveness;
}
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 handleToggleQuickMoveMenu = (isOpen : boolean) => { private readonly handleToggleQuickMoveMenu = (isOpen : boolean) => {

View File

@ -9,7 +9,7 @@ import { IPokemon } from 'app/models/Pokemon';
import { formatDexNumber, formatForm, Forms } from 'app/utils/formatter'; import { formatDexNumber, formatForm, Forms } from 'app/utils/formatter';
import { StatDisplay } from './StatDisplay'; import { StatDisplay } from './StatDisplay';
import { TypeIndicator } from './TypeIndicator'; import { TypeIndicator, TypeTheme } from './TypeIndicator';
import * as styles from 'app/components/PokemonExplorer/styles/PokemonDisplay.scss'; import * as styles from 'app/components/PokemonExplorer/styles/PokemonDisplay.scss';
@ -95,10 +95,10 @@ export class PokemonDisplay extends React.Component<IPokemonDisplay> {
}, },
); );
const type1 = <TypeIndicator type={ leaguePokemon.types.type1 } />; const type1 = <TypeIndicator type={ leaguePokemon.types.type1 } theme={ TypeTheme.SOLID }/>;
let type2 : JSX.Element | null = null; let type2 : JSX.Element | null = null;
if (leaguePokemon.types.type2) { if (leaguePokemon.types.type2) {
type2 = <TypeIndicator type={ leaguePokemon.types.type2 } />; type2 = <TypeIndicator type={ leaguePokemon.types.type2 } theme={ TypeTheme.SOLID }/>;
} }
return ( return (

View File

@ -1,3 +1,5 @@
import POGOProtos from 'pogo-protos';
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { RouteComponentProps } from 'react-router-dom'; import { RouteComponentProps } from 'react-router-dom';
@ -6,7 +8,7 @@ import classNames from 'classnames';
import { AttackTypeEffectiveness } from 'app/models/Config'; import { AttackTypeEffectiveness } from 'app/models/Config';
import { League } from 'app/models/League'; import { League } from 'app/models/League';
import { CombatMoveStats } from 'app/models/Pokemon'; import { CombatMoveStats, TypeEffectiveness } from 'app/models/Pokemon';
import * as ActionsPokemonExplorer from 'app/components/PokemonExplorer/actions'; import * as ActionsPokemonExplorer from 'app/components/PokemonExplorer/actions';
import { import {
@ -21,9 +23,10 @@ import { IRouterProps } from 'app/types';
import { LeagueIvExplorer } from 'app/components/PokemonExplorer/LeagueIvExplorer'; import { LeagueIvExplorer } from 'app/components/PokemonExplorer/LeagueIvExplorer';
import { MovesExplorer } from 'app/components/PokemonExplorer/MovesExplorer'; import { MovesExplorer } from 'app/components/PokemonExplorer/MovesExplorer';
import { PokemonDisplay } from 'app/components/PokemonExplorer/PokemonDisplay'; import { PokemonDisplay } from 'app/components/PokemonExplorer/PokemonDisplay';
import { TypeEffectiveDisplay } from 'app/components/PokemonExplorer/TypeEffectiveDisplay'; import { EffectivenessMode, TypeEffectiveDisplay } from 'app/components/PokemonExplorer/TypeEffectiveDisplay';
import { appendQueryString } from 'app/utils/navigation'; import { appendQueryString } from 'app/utils/navigation';
import { calculateTypeCoverage } from 'app/utils/types';
import * as styles from 'app/styles/PokemonApp.scss'; import * as styles from 'app/styles/PokemonApp.scss';
@ -125,6 +128,11 @@ class PokemonExplorer extends React.Component<IConnectedPokemonExplorerProps, IS
// } // }
); );
// weaknesses are indicated by types that cause super effective damage on defense
const pokemonTypeWeaknesses = leaguePokemon !== null ? this.getSuperEffectiveTypes(leaguePokemon.effectiveness) : [];
// strengths are indicuated by types that do super effective damage on offense
const moveTypeStrengths = this.getSuperEffectiveTypes(calculateTypeCoverage(selectedCombatMoves, combatMoves, attackTypeEffectiveness));
return ( return (
<div className={ styles.body }> <div className={ styles.body }>
<div className={ displayWrapperCss }> <div className={ displayWrapperCss }>
@ -135,10 +143,13 @@ class PokemonExplorer extends React.Component<IConnectedPokemonExplorerProps, IS
/> />
} }
{ widgets.types && leaguePokemon !== null && { widgets.types && leaguePokemon !== null &&
<TypeEffectiveDisplay <div className="nes-container">
effectiveness={ leaguePokemon.effectiveness } <TypeEffectiveDisplay
pokemonName={ leaguePokemon.name } mode={ EffectivenessMode.DEFENSE }
/> effectiveness={ leaguePokemon.effectiveness }
coverage={ moveTypeStrengths }
/>
</div>
} }
{ widgets.pvp && leaguePokemon !== null && { widgets.pvp && leaguePokemon !== null &&
<LeagueIvExplorer <LeagueIvExplorer
@ -156,6 +167,7 @@ class PokemonExplorer extends React.Component<IConnectedPokemonExplorerProps, IS
quickMoves={ leaguePokemon.moves.quick } quickMoves={ leaguePokemon.moves.quick }
chargeMoves={ leaguePokemon.moves.cinematic } chargeMoves={ leaguePokemon.moves.cinematic }
selectedMoves={ selectedCombatMoves } selectedMoves={ selectedCombatMoves }
pokemonTypeWeaknesses={ pokemonTypeWeaknesses }
attackTypeEffectiveness={ attackTypeEffectiveness } attackTypeEffectiveness={ attackTypeEffectiveness }
combatMoveSelectorsOpen={ combatMoveSelectorsOpen } combatMoveSelectorsOpen={ combatMoveSelectorsOpen }
handleToggleDropdownOpen={ this.handleToggleDropdownOpen } handleToggleDropdownOpen={ this.handleToggleDropdownOpen }
@ -175,6 +187,17 @@ class PokemonExplorer extends React.Component<IConnectedPokemonExplorerProps, IS
); );
} }
private readonly getSuperEffectiveTypes = (effectiveness : Map<POGOProtos.Enums.PokemonType, TypeEffectiveness>) => {
const superEffectiveTypes : Array<POGOProtos.Enums.PokemonType> = [];
Array.from(effectiveness).reduce((accumulator, currentValue) => {
if (currentValue[1] > TypeEffectiveness.NEUTRAL) {
accumulator.push(currentValue[0]);
}
return accumulator;
}, superEffectiveTypes);
return superEffectiveTypes;
}
private readonly handleToggleDropdownOpen = (menu : keyof CombatMoveSelectorsOpen, isOpen : boolean) => { private readonly handleToggleDropdownOpen = (menu : keyof CombatMoveSelectorsOpen, isOpen : boolean) => {
const combatMoveSelectorsOpen : CombatMoveSelectorsOpen = { const combatMoveSelectorsOpen : CombatMoveSelectorsOpen = {
...this.props.pokemonExplorerState.combatMoveSelectorsOpen, ...this.props.pokemonExplorerState.combatMoveSelectorsOpen,

View File

@ -1,24 +1,32 @@
import POGOProtos from 'pogo-protos';
import React from 'react'; import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { IPokemon, TypeEffectiveness } from 'app/models/Pokemon'; import { IPokemon, TypeEffectiveness } from 'app/models/Pokemon';
import { TypeIndicator } from './TypeIndicator'; import { TypeIndicator, TypeTheme } from './TypeIndicator';
import * as styles from 'app/components/PokemonExplorer/styles/TypeEffectiveDisplay.scss'; import * as styles from 'app/components/PokemonExplorer/styles/TypeEffectiveDisplay.scss';
export enum EffectivenessMode {
OFFENSE,
DEFENSE,
}
export interface ITypeEffectiveDisplayProps { export interface ITypeEffectiveDisplayProps {
pokemonName : string; mode : EffectivenessMode;
effectiveness : IPokemon['effectiveness']; effectiveness : IPokemon['effectiveness'];
coverage : Array<POGOProtos.Enums.PokemonType>;
} }
export class TypeEffectiveDisplay extends React.Component<ITypeEffectiveDisplayProps> { export class TypeEffectiveDisplay extends React.Component<ITypeEffectiveDisplayProps> {
public render() { public render() {
const { const {
mode,
effectiveness, effectiveness,
pokemonName,
} = this.props; } = this.props;
const wrapperCss = classNames( const wrapperCss = classNames(
@ -29,15 +37,15 @@ export class TypeEffectiveDisplay extends React.Component<ITypeEffectiveDisplayP
styles.indicatorWrapper, styles.indicatorWrapper,
); );
const multiplierWrapperX2Css = classNames( const multiplierWrapperX2Css = classNames(
styles.multiplierWrapper, styles.typeMultiplierWrapper,
); );
const multiplierWrapperX3Css = classNames( const multiplierWrapperX3Css = classNames(
styles.multiplierWrapper, styles.typeMultiplierWrapper,
styles.multiplierWrapperX3, styles.typeMultiplierWrapperX3,
); );
const multiplierWrapperX4Css = classNames( const multiplierWrapperX4Css = classNames(
styles.multiplierWrapper, styles.typeMultiplierWrapper,
styles.multiplierWrapperX4, styles.typeMultiplierWrapperX4,
); );
const superEffectiveX2 : Array<JSX.Element> = []; const superEffectiveX2 : Array<JSX.Element> = [];
@ -46,35 +54,45 @@ export class TypeEffectiveDisplay extends React.Component<ITypeEffectiveDisplayP
const notVeryEffectiveX2 : Array<JSX.Element> = []; const notVeryEffectiveX2 : Array<JSX.Element> = [];
const notVeryEffectiveX3 : Array<JSX.Element> = []; const notVeryEffectiveX3 : Array<JSX.Element> = [];
const notVeryEffectiveX4 : Array<JSX.Element> = []; const notVeryEffectiveX4 : Array<JSX.Element> = [];
const supereffectiveCoverage : Array<boolean> = [];
const supereffectiveCoverageX2 : Array<boolean> = [];
const notVeryEffectiveCoverage : Array<boolean> = [];
const notVeryEffectiveCoverageX2 : Array<boolean> = [];
const notVeryEffectiveCoverageX3 : Array<boolean> = [];
const notVeryEffectiveCoverageX4 : Array<boolean> = [];
effectiveness.forEach((value, key) => { effectiveness.forEach((value, key) => {
let typeIndicator : JSX.Element;
if (value === TypeEffectiveness.SUPER_EFFECTIVE ||
value === TypeEffectiveness.NOT_VERY_EFFECTIVE
) {
// using `key` because these are later transformed into an array of duplicate elements
typeIndicator = <TypeIndicator key={ key } type={ key } />;
} else {
typeIndicator = <TypeIndicator type={ key } />;
}
switch (value) { switch (value) {
case TypeEffectiveness.SUPER_EFFECTIVE_X2: case TypeEffectiveness.SUPER_EFFECTIVE_X2:
superEffectiveX2.push(typeIndicator); superEffectiveX2.push(<TypeIndicator type={ key } theme={ TypeTheme.SOLID } />);
supereffectiveCoverageX2.push(this.isTypeCovered(key));
break; break;
case TypeEffectiveness.SUPER_EFFECTIVE: case TypeEffectiveness.SUPER_EFFECTIVE:
superEffective.push(typeIndicator); superEffective.push(<TypeIndicator key={ key } type={ key } theme={ TypeTheme.SOLID } />);
supereffectiveCoverage.push(this.isTypeCovered(key));
break; break;
case TypeEffectiveness.NOT_VERY_EFFECTIVE: case TypeEffectiveness.NOT_VERY_EFFECTIVE:
notVeryEffective.push(typeIndicator); notVeryEffective.push(<TypeIndicator key={ key } type={ key } theme={ TypeTheme.OUTLINE } />);
if (mode === EffectivenessMode.DEFENSE) {
notVeryEffectiveCoverage.push(this.isTypeCovered(key));
}
break; break;
case TypeEffectiveness.IMMUNE: case TypeEffectiveness.IMMUNE:
notVeryEffectiveX2.push(typeIndicator); notVeryEffectiveX2.push(<TypeIndicator type={ key } theme={ TypeTheme.OUTLINE } />);
if (mode === EffectivenessMode.DEFENSE) {
notVeryEffectiveCoverageX2.push(this.isTypeCovered(key));
}
break; break;
case TypeEffectiveness.NOT_VERY_EFFECTIVE_X3: case TypeEffectiveness.NOT_VERY_EFFECTIVE_X3:
notVeryEffectiveX3.push(typeIndicator); notVeryEffectiveX3.push(<TypeIndicator type={ key } theme={ TypeTheme.OUTLINE } />);
if (mode === EffectivenessMode.DEFENSE) {
notVeryEffectiveCoverageX3.push(this.isTypeCovered(key));
}
break; break;
case TypeEffectiveness.IMMUNE_X2: case TypeEffectiveness.IMMUNE_X2:
notVeryEffectiveX4.push(typeIndicator); notVeryEffectiveX4.push(<TypeIndicator type={ key } theme={ TypeTheme.OUTLINE } />);
if (mode === EffectivenessMode.DEFENSE) {
notVeryEffectiveCoverageX4.push(this.isTypeCovered(key));
}
break; break;
case TypeEffectiveness.NEUTRAL: case TypeEffectiveness.NEUTRAL:
// do nothing // do nothing
@ -89,32 +107,56 @@ export class TypeEffectiveDisplay extends React.Component<ITypeEffectiveDisplayP
<div className={ wrapperCss }> <div className={ wrapperCss }>
{ (notVeryEffective.length > 0 || notVeryEffectiveX2.length > 0 || notVeryEffectiveX3.length > 0 || notVeryEffectiveX4.length > 0) && { (notVeryEffective.length > 0 || notVeryEffectiveX2.length > 0 || notVeryEffectiveX3.length > 0 || notVeryEffectiveX4.length > 0) &&
<React.Fragment> <React.Fragment>
<h4>{ pokemonName }'s Resistances<p>It's Not Very Effective...</p></h4> <h4>{ mode === EffectivenessMode.DEFENSE ? 'Resistances' : `It's not very effective...` }</h4>
<div className={ indicatorWrapperCss }> <div className={ indicatorWrapperCss }>
{ notVeryEffectiveX4.length > 0 && { notVeryEffectiveX4.length > 0 &&
notVeryEffectiveX4.map((element, index) => <div key={ `-4x${index}` } className={ multiplierWrapperX4Css }>{ element }{ element }{ element }{ element }</div>) notVeryEffectiveX4.map((element, index) =>
<div key={ `-4x${index}` } className={ `${multiplierWrapperX4Css} ${notVeryEffectiveCoverageX4[index] ? styles.isCovered : ''}` }>
{ element }{ element }{ element }{ element }
</div>
)
} }
{ notVeryEffectiveX3.length > 0 && { notVeryEffectiveX3.length > 0 &&
notVeryEffectiveX3.map((element, index) => <div key={ `-3x${index}` } className={ multiplierWrapperX3Css }>{ element }{ element }{ element }</div>) notVeryEffectiveX3.map((element, index) =>
<div key={ `-3x${index}` } className={ `${multiplierWrapperX3Css} ${notVeryEffectiveCoverageX2[index] ? styles.isCovered : ''}` }>
{ element }{ element }{ element }
</div>
)
} }
{ notVeryEffectiveX2.length > 0 && { notVeryEffectiveX2.length > 0 &&
notVeryEffectiveX2.map((element, index) => <div key={ `-2x${index}` } className={ multiplierWrapperX2Css }>{ element }{ element }</div>) notVeryEffectiveX2.map((element, index) =>
<div key={ `-2x${index}` } className={ `${multiplierWrapperX2Css} ${notVeryEffectiveCoverageX2[index] ? styles.isCovered : ''}` }>
{ element }{ element }
</div>
)
} }
{ notVeryEffective.length > 0 && { notVeryEffective.length > 0 &&
notVeryEffective notVeryEffective.map((element, index) =>
<div key={ index } className={ `${styles.typeWrapper} ${notVeryEffectiveCoverage[index] ? styles.isCovered : ''}` }>
{ element }
</div>
)
} }
</div> </div>
</React.Fragment> </React.Fragment>
} }
{ (superEffective.length > 0 || superEffectiveX2.length > 0) && { (superEffective.length > 0 || superEffectiveX2.length > 0) &&
<React.Fragment> <React.Fragment>
<h4>{ pokemonName }'s Weaknesses<p>It's Super Effective!</p></h4> <h4>{ mode === EffectivenessMode.DEFENSE ? 'Weaknesses' : `It's super effective!` }</h4>
<div className={ indicatorWrapperCss }> <div className={ indicatorWrapperCss }>
{ superEffectiveX2.length > 0 && { superEffectiveX2.length > 0 &&
superEffectiveX2.map((element, index) => <div key={ `+2x${index}` } className={ multiplierWrapperX2Css }>{ element }{ element }</div>) superEffectiveX2.map((element, index) =>
<div key={ `+2x${index}` } className={ `${multiplierWrapperX2Css} ${supereffectiveCoverageX2[index] ? styles.isCovered : ''}` }>
{ element }{ element }
</div>
)
} }
{ superEffective.length > 0 && { superEffective.length > 0 &&
superEffective superEffective.map((element, index) =>
<div key={ index } className={ `${styles.typeWrapper} ${supereffectiveCoverage[index] ? styles.isCovered : ''}` }>
{ element }
</div>
)
} }
</div> </div>
</React.Fragment> </React.Fragment>
@ -122,4 +164,10 @@ export class TypeEffectiveDisplay extends React.Component<ITypeEffectiveDisplayP
</div> </div>
); );
} }
private readonly isTypeCovered = (type : POGOProtos.Enums.PokemonType) => {
return this.props.coverage.some((coverageType) => {
return coverageType === type;
});
}
} }

View File

@ -8,27 +8,37 @@ import { formatType } from 'app/utils/formatter';
import * as styles from 'app/components/PokemonExplorer/styles/TypeIndicator.scss'; import * as styles from 'app/components/PokemonExplorer/styles/TypeIndicator.scss';
export enum TypeTheme {
SOLID,
OUTLINE,
}
export interface ITypeEffectiveDisplayProps { export interface ITypeEffectiveDisplayProps {
className? : string; className? : string;
type : POGOProtos.Enums.PokemonType; type : POGOProtos.Enums.PokemonType;
theme : TypeTheme;
} }
export class TypeIndicator extends React.Component<ITypeEffectiveDisplayProps> { export class TypeIndicator extends React.Component<ITypeEffectiveDisplayProps> {
public render() { public render() {
const { className, type } = this.props; const {
className,
theme,
type,
} = this.props;
const containerCss = classNames( const containerCss = classNames(
'nes-container', 'nes-container',
'with-title', 'with-title',
);
const containerRoundCss = classNames(
containerCss,
'is-rounded', 'is-rounded',
); );
const pokemonTypeCss = classNames( const pokemonTypeCss = classNames(
className, className,
containerRoundCss, containerCss,
styles.pokemonType, styles.pokemonType,
{
outline: theme === TypeTheme.OUTLINE
}
); );
return <div className={ `${pokemonTypeCss} ${formatType(type)}` }>{ formatType(type) }</div>; return <div className={ `${pokemonTypeCss} ${formatType(type)}` }>{ formatType(type) }</div>;

View File

@ -1,8 +1,12 @@
@import '~styles/Variables.scss'; @import '~styles/Variables.scss';
.multiplierWrapper { .typeWrapper,
.typeMultiplierWrapper {
position: relative; position: relative;
z-index: 0; // so the contents don't show up over the overlay z-index: 0; // so the contents don't show up over the overlay
}
.typeMultiplierWrapper {
padding-top: 6px; padding-top: 6px;
padding-right: 6px; padding-right: 6px;
@ -31,7 +35,7 @@
z-index: 0; z-index: 0;
} }
&.multiplierWrapperX3 { &.typeMultiplierWrapperX3 {
padding-top: 12px; padding-top: 12px;
padding-right: 12px; padding-right: 12px;
@ -44,7 +48,7 @@
} }
} }
&.multiplierWrapperX4 { &.typeMultiplierWrapperX4 {
padding-top: 18px; padding-top: 18px;
padding-right: 18px; padding-right: 18px;
@ -69,12 +73,6 @@
margin-top: 1em; margin-top: 1em;
} }
h4 p {
font-size: 0.7em;
color: $main-font-secondary-color;
margin: 0;
}
.indicatorWrapper { .indicatorWrapper {
display: flex; display: flex;
flex-flow: row wrap; flex-flow: row wrap;
@ -85,23 +83,40 @@
height: 0%; // stop single effectiveness indicators from growing to match height/margin of multiple effectiveness indicators height: 0%; // stop single effectiveness indicators from growing to match height/margin of multiple effectiveness indicators
} }
.multiplierWrapper { .typeMultiplierWrapper {
width: auto; width: auto;
margin-right: 2px; margin-right: 2px;
&.multiplierWrapperX3 { &.typeMultiplierWrapperX3 {
margin-right: -4px; margin-right: -4px;
} }
&.multiplierWrapperX4 { &.typeMultiplierWrapperX4 {
margin-right: -10px; margin-right: -10px;
} }
} }
& > *, .typeWrapper > *,
.multiplierWrapper > * { .typeMultiplierWrapper > * {
flex-basis: unset; flex-basis: unset;
width: 6.75rem; width: 6.75rem;
} }
} }
} }
.isCovered {
position: relative;
&::before {
// inspired by nes.css's `.nes-checkbox`
content: "";
position: absolute;
right: 25px;
bottom: 20px;
z-index: 10;
width: 2px;
height: 2px;
color: $main-success;
box-shadow: 18px 2px, 20px 2px, 16px 4px, 18px 4px, 20px 4px, 2px 6px, 14px 6px, 16px 6px, 2px 8px, 4px 8px, 12px 8px, 14px 8px, 4px 10px, 6px 10px, 10px 10px, 12px 10px, 6px 12px, 8px 12px, 10px 12px, 8px 14px;
}
}

View File

@ -1,7 +1,9 @@
// This file is automatically generated. // This file is automatically generated.
// Please do not change this file! // Please do not change this file!
export const indicatorWrapper: string; export const indicatorWrapper: string;
export const multiplierWrapper: string; export const isCovered: string;
export const multiplierWrapperX3: string; export const typeMultiplierWrapper: string;
export const multiplierWrapperX4: string; export const typeMultiplierWrapperX3: string;
export const typeMultiplierWrapperX4: string;
export const typeWrapper: string;
export const wrapper: string; export const wrapper: string;

View File

@ -28,6 +28,11 @@
&::after { &::after {
@include rounded-box-shadow($primary); @include rounded-box-shadow($primary);
} }
&:global(.outline) {
color: $primary;
background-color: $contrast;
}
} }
} }
} }

44
src/ts/app/utils/types.ts Normal file
View File

@ -0,0 +1,44 @@
import POGOProtos from 'pogo-protos';
import { AttackTypeEffectiveness } from 'app/models/Config';
import { CombatMoveStats, ICombatMoveStats, IPokemonMove, TypeEffectiveness } from 'app/models/Pokemon';
import { SelectedCombatMoves } from 'app/components/PokemonExplorer/types';
export const calculateTypeCoverage = (
selectedMoves : SelectedCombatMoves,
movesById : CombatMoveStats,
attackTypeEffectiveness : AttackTypeEffectiveness,
) => {
const calculatedffectiveness : Map<POGOProtos.Enums.PokemonType, TypeEffectiveness> = new Map();
Object.values(selectedMoves).forEach((move) => {
const moveType = getMoveType(move, movesById);
if (moveType !== null) {
const moveEffectiveness = attackTypeEffectiveness.get(moveType);
if (typeof moveEffectiveness !== 'undefined') {
moveEffectiveness.forEach((effectiveness, type) => {
const currentEffectiveness = calculatedffectiveness.get(type);
if (typeof currentEffectiveness === 'undefined' || effectiveness > currentEffectiveness) {
calculatedffectiveness.set(type, effectiveness);
}
});
}
}
});
return calculatedffectiveness;
};
export const getMoveType = (
move : IPokemonMove | null,
movesById : CombatMoveStats,
) => {
let moveStats : ICombatMoveStats | null = null;
if (move !== null) {
moveStats = movesById.get(move.id) || null;
}
if (moveStats !== null) {
return moveStats.type;
}
return null;
};