Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Added CP based calculations #272

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from Jul 28, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 44 additions & 2 deletions src/main/java/com/pokegoapi/api/pokemon/Pokemon.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import POGOProtos.Networking.Requests.RequestTypeOuterClass.RequestType;
import POGOProtos.Networking.Responses.EvolvePokemonResponseOuterClass.EvolvePokemonResponse;
import POGOProtos.Networking.Responses.NicknamePokemonResponseOuterClass.NicknamePokemonResponse;
import POGOProtos.Networking.Responses.RecycleInventoryItemResponseOuterClass;
import POGOProtos.Networking.Responses.ReleasePokemonResponseOuterClass.ReleasePokemonResponse;
import POGOProtos.Networking.Responses.ReleasePokemonResponseOuterClass.ReleasePokemonResponse.Result;
import POGOProtos.Networking.Responses.SetFavoritePokemonResponseOuterClass.SetFavoritePokemonResponse;
Expand All @@ -42,6 +41,7 @@
import com.pokegoapi.api.inventory.Item;
import com.pokegoapi.api.map.pokemon.EvolutionResult;
import com.pokegoapi.exceptions.LoginFailedException;
import com.pokegoapi.exceptions.NoSuchItemException;
import com.pokegoapi.exceptions.RemoteServerException;
import com.pokegoapi.main.ServerRequest;
import com.pokegoapi.util.Log;
Expand Down Expand Up @@ -189,7 +189,7 @@ public UpgradePokemonResponse.Result powerUp() throws LoginFailedException, Remo
}
}

/**
/**dus
* Evolve evolution result.
*
* @return the evolution result
Expand Down Expand Up @@ -390,6 +390,48 @@ public double getBaseFleeRate() {
return getMeta().getBaseFleeRate();
}

public float getLevel() {
return PokemonCpUtils.getLevelFromCpMultiplier(proto.getCpMultiplier() + proto.getAdditionalCpMultiplier());
}

/**
* @return The maximum CP for this pokemon
*/
public int getMaxCp() throws NoSuchItemException {
PokemonMeta pokemonMeta = PokemonMetaRegistry.getMeta(proto.getPokemonId());
if (pokemonMeta == null) {
throw new NoSuchItemException("Cannot find meta data for " + proto.getPokemonId().name());
}
int attack = proto.getIndividualAttack() + pokemonMeta.getBaseAttack();
int defense = proto.getIndividualDefense() + pokemonMeta.getBaseDefense();
int stamina = proto.getIndividualStamina() + pokemonMeta.getBaseStamina();
return PokemonCpUtils.getMaxCp(attack, defense, stamina);
}

/**
* @return The CP for this pokemon after powerup
*/
public int getCpAfterPowerup() {
return PokemonCpUtils.getCpAfterPowerup(proto.getCp(),
proto.getCpMultiplier() + proto.getAdditionalCpMultiplier());
}

/**
* @return Cost of candy for a powerup
*/
public int getCandyCostsForPowerup() {
return PokemonCpUtils.getCandyCostsForPowerup(proto.getCpMultiplier() + proto.getAdditionalCpMultiplier(),
proto.getNumUpgrades());
}

/**
* @return Cost of stardust for a powerup
*/
public int getStardustCostsForPowerup() {
return PokemonCpUtils.getStartdustCostsForPowerup(proto.getCpMultiplier() + proto.getAdditionalCpMultiplier(),
proto.getNumUpgrades());
}

public PokemonIdOuterClass.PokemonId getParent() {
return getMeta().getParentId();
}
Expand Down
256 changes: 256 additions & 0 deletions src/main/java/com/pokegoapi/api/pokemon/PokemonCpUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.pokegoapi.api.pokemon;

import java.util.HashMap;
import java.util.Map;

/**
* Information in this class is based on:
* http://pokemongo.gamepress.gg/cp-multiplier
* and
* http://pokemongo.gamepress.gg/pokemon-stats-advanced
*/
class PokemonCpUtils {
private static final Map<Float,Float> LEVEL_CPMULTIPLIER = new HashMap<>();

static {
LEVEL_CPMULTIPLIER.put(1f, 0.094f);
LEVEL_CPMULTIPLIER.put(1.5f, 0.135137432f);
LEVEL_CPMULTIPLIER.put(2f, 0.16639787f);
LEVEL_CPMULTIPLIER.put(2.5f, 0.192650919f);
LEVEL_CPMULTIPLIER.put(3f, 0.21573247f);
LEVEL_CPMULTIPLIER.put(3.5f, 0.236572661f);
LEVEL_CPMULTIPLIER.put(4f, 0.25572005f);
LEVEL_CPMULTIPLIER.put(4.5f, 0.273530381f);
LEVEL_CPMULTIPLIER.put(5f, 0.29024988f);
LEVEL_CPMULTIPLIER.put(5.5f, 0.306057377f);
LEVEL_CPMULTIPLIER.put(6f, 0.3210876f);
LEVEL_CPMULTIPLIER.put(6.5f, 0.335445036f);
LEVEL_CPMULTIPLIER.put(7f, 0.34921268f);
LEVEL_CPMULTIPLIER.put(7.5f, 0.362457751f);
LEVEL_CPMULTIPLIER.put(8f, 0.37523559f);
LEVEL_CPMULTIPLIER.put(8.5f, 0.387592406f);
LEVEL_CPMULTIPLIER.put(9f, 0.39956728f);
LEVEL_CPMULTIPLIER.put(9.5f, 0.411193551f);
LEVEL_CPMULTIPLIER.put(10f, 0.42250001f);
LEVEL_CPMULTIPLIER.put(10.5f, 0.432926419f);
LEVEL_CPMULTIPLIER.put(11f, 0.44310755f);
LEVEL_CPMULTIPLIER.put(11.5f, 0.453059958f);
LEVEL_CPMULTIPLIER.put(12f, 0.46279839f);
LEVEL_CPMULTIPLIER.put(12.5f, 0.472336083f);
LEVEL_CPMULTIPLIER.put(13f, 0.48168495f);
LEVEL_CPMULTIPLIER.put(13.5f, 0.4908558f);
LEVEL_CPMULTIPLIER.put(14f, 0.49985844f);
LEVEL_CPMULTIPLIER.put(14.5f, 0.508701765f);
LEVEL_CPMULTIPLIER.put(15f, 0.51739395f);
LEVEL_CPMULTIPLIER.put(15.5f, 0.525942511f);
LEVEL_CPMULTIPLIER.put(16f, 0.53435433f);
LEVEL_CPMULTIPLIER.put(16.5f, 0.542635767f);
LEVEL_CPMULTIPLIER.put(17f, 0.55079269f);
LEVEL_CPMULTIPLIER.put(17.5f, 0.558830576f);
LEVEL_CPMULTIPLIER.put(18f, 0.56675452f);
LEVEL_CPMULTIPLIER.put(18.5f, 0.574569153f);
LEVEL_CPMULTIPLIER.put(19f, 0.58227891f);
LEVEL_CPMULTIPLIER.put(19.5f, 0.589887917f);
LEVEL_CPMULTIPLIER.put(20f, 0.59740001f);
LEVEL_CPMULTIPLIER.put(20.5f, 0.604818814f);
LEVEL_CPMULTIPLIER.put(21f, 0.61215729f);
LEVEL_CPMULTIPLIER.put(21.5f, 0.619399365f);
LEVEL_CPMULTIPLIER.put(22f, 0.62656713f);
LEVEL_CPMULTIPLIER.put(22.5f, 0.633644533f);
LEVEL_CPMULTIPLIER.put(23f, 0.64065295f);
LEVEL_CPMULTIPLIER.put(23.5f, 0.647576426f);
LEVEL_CPMULTIPLIER.put(24f, 0.65443563f);
LEVEL_CPMULTIPLIER.put(24.5f, 0.661214806f);
LEVEL_CPMULTIPLIER.put(25f, 0.667934f);
LEVEL_CPMULTIPLIER.put(25.5f, 0.674577537f);
LEVEL_CPMULTIPLIER.put(26f, 0.68116492f);
LEVEL_CPMULTIPLIER.put(26.5f, 0.687680648f);
LEVEL_CPMULTIPLIER.put(27f, 0.69414365f);
LEVEL_CPMULTIPLIER.put(27.5f, 0.700538673f);
LEVEL_CPMULTIPLIER.put(28f, 0.70688421f);
LEVEL_CPMULTIPLIER.put(28.5f, 0.713164996f);
LEVEL_CPMULTIPLIER.put(29f, 0.71939909f);
LEVEL_CPMULTIPLIER.put(29.5f, 0.725571552f);
LEVEL_CPMULTIPLIER.put(30f, 0.7317f);
LEVEL_CPMULTIPLIER.put(30.5f, 0.734741009f);
LEVEL_CPMULTIPLIER.put(31f, 0.73776948f);
LEVEL_CPMULTIPLIER.put(31.5f, 0.740785574f);
LEVEL_CPMULTIPLIER.put(32f, 0.74378943f);
LEVEL_CPMULTIPLIER.put(32.5f, 0.746781211f);
LEVEL_CPMULTIPLIER.put(33f, 0.74976104f);
LEVEL_CPMULTIPLIER.put(33.5f, 0.752729087f);
LEVEL_CPMULTIPLIER.put(34f, 0.75568551f);
LEVEL_CPMULTIPLIER.put(34.5f, 0.758630378f);
LEVEL_CPMULTIPLIER.put(35f, 0.76156384f);
LEVEL_CPMULTIPLIER.put(35.5f, 0.764486065f);
LEVEL_CPMULTIPLIER.put(36f, 0.76739717f);
LEVEL_CPMULTIPLIER.put(36.5f, 0.770297266f);
LEVEL_CPMULTIPLIER.put(37f, 0.7731865f);
LEVEL_CPMULTIPLIER.put(37.5f, 0.776064962f);
LEVEL_CPMULTIPLIER.put(38f, 0.77893275f);
LEVEL_CPMULTIPLIER.put(38.5f, 0.781790055f);
LEVEL_CPMULTIPLIER.put(39f, 0.78463697f);
LEVEL_CPMULTIPLIER.put(39.5f, 0.787473578f);
LEVEL_CPMULTIPLIER.put(40f, 0.79030001f);
}

private static float getLevel(float cpMuliplier) {
float level;
if (cpMuliplier < 0.734f) {
// compute polynomial approximation obtained by regression
level = 58.35178527f * cpMuliplier * cpMuliplier - 2.838007664f * cpMuliplier + 0.8539209906f;
} else {
// compute linear approximation obtained by regression
level = 171.0112688f * cpMuliplier - 95.20425243f;
}
// round to nearest .5 value and return
return Math.round((level) * 2) / 2.0f;
}

/**
* Get the level from the cp multiplier
* @param cpMultiplier All CP multiplier values combined
* @return Level
*/
static float getLevelFromCpMultiplier(float cpMultiplier) {
return getLevel(cpMultiplier);
}

/**
* Get the maximum CP from the values
* @param attack All attack values combined
* @param defense All defense values combined
* @param stamina All stamina values combined
* @return Maximum CP for these levels
*/
static int getMaxCp(int attack, int defense, int stamina) {
float maxCpMultplier = LEVEL_CPMULTIPLIER.get(40f);
return (int)(attack * Math.pow(defense, 0.5) * Math.pow(stamina, 0.5) * Math.pow(maxCpMultplier,2) / 10f);
}

/**
* Get the CP after powerup
* @param cp Current CP level
* @param cpMultiplier All CP multiplier values combined
* @return New CP level
*/
static int getCpAfterPowerup(float cp, float cpMultiplier) {
// Based on http://pokemongo.gamepress.gg/power-up-costs
float level = getLevelFromCpMultiplier(cpMultiplier);
if (level <= 10) {
return (int)((cp * 0.009426125469) / Math.pow(cpMultiplier, 2));
}
if (level <= 20) {
return (int)((cp * 0.008919025675) / Math.pow(cpMultiplier, 2));
}
if (level <= 30) {
return (int)((cp * 0.008924905903) / Math.pow(cpMultiplier, 2));
}
return (int)((cp * 0.00445946079) / Math.pow(cpMultiplier, 2));
}

/**
* Get the amount of stardust required to do a powerup
* @param cpMultiplier All CP multiplier values combined
* @param powerups Number of previous powerups
* @return Amount of stardust
*/
static int getStartdustCostsForPowerup(float cpMultiplier, int powerups) {
// Based on http://pokemongo.gamepress.gg/power-up-costs
float level = getLevelFromCpMultiplier(cpMultiplier);
if (level <= 3 && powerups <= 4) {
return 200;
}
if (level <= 4 && powerups <= 8) {
return 400;
}
if (level <= 7 && powerups <= 12) {
return 600;
}
if (level <= 8 && powerups <= 16) {
return 800;
}
if (level <= 11 && powerups <= 20) {
return 1000;
}
if (level <= 13 && powerups <= 24) {
return 1300;
}
if (level <= 15 && powerups <= 28) {
return 1600;
}
if (level <= 17 && powerups <= 32) {
return 1900;
}
if (level <= 19 && powerups <= 36) {
return 2200;
}
if (level <= 21 && powerups <= 40) {
return 2500;
}
if (level <= 23 && powerups <= 44) {
return 3000;
}
if (level <= 25 && powerups <= 48) {
return 3500;
}
if (level <= 27 && powerups <= 52) {
return 4000;
}
if (level <= 29 && powerups <= 56) {
return 4500;
}
if (level <= 31 && powerups <= 60) {
return 5000;
}
if (level <= 33 && powerups <= 64) {
return 6000;
}
if (level <= 35 && powerups <= 68) {
return 7000;
}
if (level <= 37 && powerups <= 72) {
return 8000;
}
if (level <= 39 && powerups <= 76) {
return 9000;
}
return 10000;
}

/**
* Get the amount of candy required to do a powerup
* @param cpMultiplier All CP multiplier values combined
* @param powerups Number of previous powerups
* @return Amount of candy
*/
static int getCandyCostsForPowerup(float cpMultiplier, int powerups) {
// Based on http://pokemongo.gamepress.gg/power-up-costs
float level = getLevelFromCpMultiplier(cpMultiplier);
if (level <= 13 && powerups <= 20 ) {
return 1;
}
if (level <= 21 && powerups <= 36 ) {
return 2;
}
if (level <= 31 && powerups <= 60 ) {
return 3;
}
return 4;
}
}