diff --git a/app/src/main/java/com/kamron/pogoiv/GoIVSettings.java b/app/src/main/java/com/kamron/pogoiv/GoIVSettings.java index f3561e6dc..16a485bcf 100644 --- a/app/src/main/java/com/kamron/pogoiv/GoIVSettings.java +++ b/app/src/main/java/com/kamron/pogoiv/GoIVSettings.java @@ -53,7 +53,7 @@ public class GoIVSettings { public static final String SHOW_TRANSLATED_POKEMON_NAME = "showTranslatedPokemonName"; public static final String HAS_WARNED_USER_NO_SCREENREC = "GOIV_hasWarnedUserNoScreenRec"; public static final String COPY_TO_CLIPBOARD_SHOW_TOAST = "copyToClipboardShowToast"; - public static final String AUTO_APPRAISAL_SCAN_DELAY = "autoAppraisalScanDelay"; + public static final String AUTO_APPRAISAL_SCAN_DELAY = "appraisalScanDelay"; public static final String AUTO_OPEN_APPRAISE_DIALOGUE = "autoOpenAppraiseDialogue"; public static final String QUICK_IV_PREVIEW = "quick_iv_preview"; public static final String QUICK_IV_PREVIEW_CLIPBOARD = "quick_iv_preview_clipboard"; diff --git a/app/src/main/java/com/kamron/pogoiv/pokeflycomponents/AppraisalManager.java b/app/src/main/java/com/kamron/pogoiv/pokeflycomponents/AppraisalManager.java index 389cc9500..714edf26f 100644 --- a/app/src/main/java/com/kamron/pogoiv/pokeflycomponents/AppraisalManager.java +++ b/app/src/main/java/com/kamron/pogoiv/pokeflycomponents/AppraisalManager.java @@ -1,18 +1,19 @@ package com.kamron.pogoiv.pokeflycomponents; -import android.content.Context; import android.graphics.Bitmap; import android.os.Handler; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import com.kamron.pogoiv.GoIVSettings; -import com.kamron.pogoiv.R; +import com.kamron.pogoiv.Pokefly; import com.kamron.pogoiv.ScreenGrabber; import com.kamron.pogoiv.pokeflycomponents.ocrhelper.OcrHelper; +import com.kamron.pogoiv.scanlogic.IVCombination; +import timber.log.Timber; import java.util.ArrayList; -import java.util.HashSet; +import java.util.Arrays; /** * Created by Johan on 2016-12-01. @@ -20,55 +21,35 @@ */ public class AppraisalManager { - private ScreenScan autoScreenScanner = new ScreenScan(); + private ScreenScan autoScreenScanner; private Handler handler = new Handler(); - private GoIVSettings settings; + private Pokefly pokefly; private ScreenGrabber screenGrabber; private ArrayList eventListeners = new ArrayList<>(); - private static final int SCANRETRIES = 3; // max num of retries if appraisal text doesn't match - private static final int RETRYDELAY = 50; // ms delay between retry scans + private static final int SCANRETRIES = 5; // max num of retries if appraisal text doesn't match + private static final int RETRYDELAY = 200; // ms delay between retry scans private int numTouches = 0; - private int numRetries = 0; private boolean autoAppraisalDone = false; - public IVSumRange appraisalIVSumRange = IVSumRange.UNKNOWN; - public HashSet highestStats = new HashSet<>(); - public IVValueRange appraisalHighestStatValueRange = IVValueRange.UNKNOWN; - public HashSet statModifiers = new HashSet<>(); - - //Appraisal phrases - private String highest_stat_att; - private String highest_stat_def; - private String highest_stat_hp; - private String ivrange1_phrase1; - private String ivrange1_phrase2; - private String ivrange2_phrase1; - private String ivrange2_phrase2; - private String ivrange3_phrase1; - private String ivrange3_phrase2; - private String ivrange4_phrase1; - private String ivrange4_phrase2; - private String statsrange1_phrase1; - private String statsrange1_phrase2; - private String statsrange2_phrase1; - private String statsrange2_phrase2; - private String statsrange3_phrase1; - private String statsrange3_phrase2; - private String statsrange4_phrase1; - private String statsrange4_phrase2; - + public int attack = 0; + public boolean attackValid = false; + public int defense = 0; + public boolean defenseValid = false; + public int stamina = 0; + public boolean staminaValid = false; /** * Instantiate the appraisal logic handler. If screenGrabber is not null, enables auto appraisal. * @param screenGrabber The helper class that gets the screenshots from the MediaProjection API */ - public AppraisalManager(@Nullable ScreenGrabber screenGrabber, @NonNull Context context) { + public AppraisalManager(@Nullable ScreenGrabber screenGrabber, @NonNull Pokefly pokefly) { this.screenGrabber = screenGrabber; - settings = GoIVSettings.getInstance(context); - getAppraisalPhrases(context); + GoIVSettings settings = GoIVSettings.getInstance(pokefly); + this.autoScreenScanner = new ScreenScan(settings.getAutoAppraisalScanDelay()); + this.pokefly = pokefly; } public void addOnAppraisalEventListener(OnAppraisalEventListener eventListener) { @@ -79,68 +60,8 @@ public void removeOnAppraisalEventListener(OnAppraisalEventListener eventListene eventListeners.remove(eventListener); } - private void getAppraisalPhrases(@NonNull Context context) { - highest_stat_att = context.getString(R.string.highest_stat_att); - highest_stat_def = context.getString(R.string.highest_stat_def); - highest_stat_hp = context.getString(R.string.highest_stat_hp); - - if (settings.playerTeam() == 0) { - ivrange1_phrase1 = context.getString(R.string.mystic_percentage1_phrase1); - ivrange1_phrase2 = context.getString(R.string.mystic_percentage1_phrase2); - ivrange2_phrase1 = context.getString(R.string.mystic_percentage2_phrase1); - ivrange2_phrase2 = context.getString(R.string.mystic_percentage2_phrase2); - ivrange3_phrase1 = context.getString(R.string.mystic_percentage3_phrase1); - ivrange3_phrase2 = context.getString(R.string.mystic_percentage3_phrase2); - ivrange4_phrase1 = context.getString(R.string.mystic_percentage4_phrase1); - ivrange4_phrase2 = context.getString(R.string.mystic_percentage4_phrase2); - statsrange1_phrase1 = context.getString(R.string.mystic_ivrange1_phrase1); - statsrange1_phrase2 = context.getString(R.string.mystic_ivrange1_phrase2); - statsrange2_phrase1 = context.getString(R.string.mystic_ivrange2_phrase1); - statsrange2_phrase2 = context.getString(R.string.mystic_ivrange2_phrase2); - statsrange3_phrase1 = context.getString(R.string.mystic_ivrange3_phrase1); - statsrange3_phrase2 = context.getString(R.string.mystic_ivrange3_phrase2); - statsrange4_phrase1 = context.getString(R.string.mystic_ivrange4_phrase1); - statsrange4_phrase2 = context.getString(R.string.mystic_ivrange4_phrase2); - } else if (settings.playerTeam() == 1) { - ivrange1_phrase1 = context.getString(R.string.valor_percentage1_phrase1); - ivrange1_phrase2 = context.getString(R.string.valor_percentage1_phrase2); - ivrange2_phrase1 = context.getString(R.string.valor_percentage2_phrase1); - ivrange2_phrase2 = context.getString(R.string.valor_percentage2_phrase2); - ivrange3_phrase1 = context.getString(R.string.valor_percentage3_phrase1); - ivrange3_phrase2 = context.getString(R.string.valor_percentage3_phrase2); - ivrange4_phrase1 = context.getString(R.string.valor_percentage4_phrase1); - ivrange4_phrase2 = context.getString(R.string.valor_percentage4_phrase2); - statsrange1_phrase1 = context.getString(R.string.valor_ivrange1_phrase1); - statsrange1_phrase2 = context.getString(R.string.valor_ivrange1_phrase2); - statsrange2_phrase1 = context.getString(R.string.valor_ivrange2_phrase1); - statsrange2_phrase2 = context.getString(R.string.valor_ivrange2_phrase2); - statsrange3_phrase1 = context.getString(R.string.valor_ivrange3_phrase1); - statsrange3_phrase2 = context.getString(R.string.valor_ivrange3_phrase2); - statsrange4_phrase1 = context.getString(R.string.valor_ivrange4_phrase1); - statsrange4_phrase2 = context.getString(R.string.valor_ivrange4_phrase2); - } else { - ivrange1_phrase1 = context.getString(R.string.instinct_percentage1_phrase1); - ivrange1_phrase2 = context.getString(R.string.instinct_percentage1_phrase2); - ivrange2_phrase1 = context.getString(R.string.instinct_percentage2_phrase1); - ivrange2_phrase2 = context.getString(R.string.instinct_percentage2_phrase2); - ivrange3_phrase1 = context.getString(R.string.instinct_percentage3_phrase1); - ivrange3_phrase2 = context.getString(R.string.instinct_percentage3_phrase2); - ivrange4_phrase1 = context.getString(R.string.instinct_percentage4_phrase1); - ivrange4_phrase2 = context.getString(R.string.instinct_percentage4_phrase2); - statsrange1_phrase1 = context.getString(R.string.instinct_ivrange1_phrase1); - statsrange1_phrase2 = context.getString(R.string.instinct_ivrange1_phrase2); - statsrange2_phrase1 = context.getString(R.string.instinct_ivrange2_phrase1); - statsrange2_phrase2 = context.getString(R.string.instinct_ivrange2_phrase2); - statsrange3_phrase1 = context.getString(R.string.instinct_ivrange3_phrase1); - statsrange3_phrase2 = context.getString(R.string.instinct_ivrange3_phrase2); - statsrange4_phrase1 = context.getString(R.string.instinct_ivrange4_phrase1); - statsrange4_phrase2 = context.getString(R.string.instinct_ivrange4_phrase2); - } - } - public void screenTouched() { numTouches++; - numRetries = 0; // First touch is usually the Pokemon Go menu button in the bottom right of the Pokemon screen. // Although, it's entirely possible for the user to touch the area below (or above) GoIV an unlimited number @@ -152,273 +73,179 @@ public void screenTouched() { eventListener.highlightActiveUserInterface(); } } else if ((numTouches > 2) && (!autoAppraisalDone)) { - for (OnAppraisalEventListener eventListener : eventListeners) { - eventListener.highlightActiveUserInterface(); - } // Scan Appraisal text after the configured delay. - scanAppraisalText(settings.getAutoAppraisalScanDelay()); - } else if (autoAppraisalDone) { - for (OnAppraisalEventListener eventListener : eventListeners) { - eventListener.resetActivatedUserInterface(); - } + autoScreenScanner.post(); } } - /** - * Common method for setting a .postDelayed handler to scan the appraisal text after the specified milliseconds. - * This allows for the same function to be used upon initial scan as well as the follow-up retry scans while - * waiting for the appraisal text animation to finish. - * - * @param delay_millis The number of milliseconds that the scan will be delayed before firing off. - */ - private void scanAppraisalText(int delay_millis) { - handler.removeCallbacks(autoScreenScanner); - handler.postDelayed(autoScreenScanner, delay_millis); - } - /** * Resets any necessary variables to their default states for the next Appraisal process. */ public void reset() { // Delete values - appraisalIVSumRange = IVSumRange.UNKNOWN; - highestStats.clear(); - appraisalHighestStatValueRange = IVValueRange.UNKNOWN; - statModifiers.clear(); + attack = 0; + attackValid = false; + defense = 0; + defenseValid = false; + stamina = 0; + staminaValid = false; // Reset state numTouches = 0; - numRetries = 0; autoAppraisalDone = false; - - for (OnAppraisalEventListener eventListener : eventListeners) { - eventListener.resetActivatedUserInterface(); - } } - /** - * Alters the state of the AppraisalManager instance to reflect the added information of the appraise text. - * - * @param appraiseText Text such as "...pokemon is breathtaking..." - * @param hash the hash of the bitmap used by ocr - */ - private void addInfoFromAppraiseText(String appraiseText, String hash) { - boolean match = false; - - if (appraisalIVSumRange == IVSumRange.UNKNOWN) { - // Only if none of the IVRange checkboxes have been checked. - // See if appraiseText matches any of the IVRange strings - match = setIVRangeWith(appraiseText); - } - if (!match && appraisalIVSumRange != IVSumRange.UNKNOWN) { - // Only if IVRange is done and have not matched yet. - // See if appraiseText matches any of the Highest Stats strings - match = setHighestStatsWith(appraiseText); - } - if (!match) { // Lastly, check if the appraiseText matches any of the Stat phrases - match = setStatsRangeWith(appraiseText); - } - if (!match && numRetries < SCANRETRIES) { // If nothing matched and we have not yet reached maximum # of retries - numRetries++; - // Nothing matched, so this phrase should be thrown away. - OcrHelper.removeEntryFromAppraisalCache(settings, hash); - // Let's schedule another scan to see if animation has finished. - scanAppraisalText(RETRYDELAY); - } else if (!match) { // Nothing matched and we've ran out of retry attempts. - // Nothing matched, so this phrase should be thrown away. - OcrHelper.removeEntryFromAppraisalCache(settings, hash); - } - } - - /** - * Selects the appropriate appraisalStatsGroup Checkbox depending on which phrase is matched. - * - * @param appraiseText the text to interpret. - * @return boolean returns true if the appraiseText matched a configured phrase. - */ - private boolean setStatsRangeWith(String appraiseText) { - if (appraiseText.toLowerCase().contains(statsrange1_phrase1) - || (appraiseText.toLowerCase().contains(statsrange1_phrase2))) { - for (OnAppraisalEventListener eventListener: eventListeners) { - eventListener.selectIVValueRange(IVValueRange.RANGE_15); - eventListener.highlightActiveUserInterface(); - } - autoAppraisalDone = true; - return true; - } - if (appraiseText.toLowerCase().contains(statsrange2_phrase1) - || (appraiseText.toLowerCase().contains(statsrange2_phrase2))) { - for (OnAppraisalEventListener eventListener: eventListeners) { - eventListener.selectIVValueRange(IVValueRange.RANGE_13_14); - eventListener.highlightActiveUserInterface(); - } - autoAppraisalDone = true; - return true; - } - if (appraiseText.toLowerCase().contains(statsrange3_phrase1) - || (appraiseText.toLowerCase().contains(statsrange3_phrase2))) { - for (OnAppraisalEventListener eventListener: eventListeners) { - eventListener.selectIVValueRange(IVValueRange.RANGE_8_12); - eventListener.highlightActiveUserInterface(); - } - autoAppraisalDone = true; - return true; - } - if (appraiseText.toLowerCase().contains(statsrange4_phrase1) - || (appraiseText.toLowerCase().contains(statsrange4_phrase2))) { - for (OnAppraisalEventListener eventListener: eventListeners) { - eventListener.selectIVValueRange(IVValueRange.RANGE_0_7); - eventListener.highlightActiveUserInterface(); - } + private void addStatScanResult(@Nullable IVCombination combination) { + if (combination != null) { + attack = combination.att; + attackValid = true; + defense = combination.def; + defenseValid = true; + stamina = combination.sta; + staminaValid = true; autoAppraisalDone = true; - return true; - } - return false; - } - - /** - * Sets each of the highest stats as found within the appraisal phrases given. - * - * @param appraiseText the text to interpret. - * @return boolean returns true if one of the highest stats phrase was matched. - */ - private boolean setHighestStatsWith(String appraiseText) { - if (appraiseText.toLowerCase().contains(highest_stat_att)) { for (OnAppraisalEventListener eventListener : eventListeners) { - eventListener.selectHighestStat(HighestStat.ATK); + eventListener.refreshSelection(); } - return true; } - if (appraiseText.toLowerCase().contains(highest_stat_def)) { - for (OnAppraisalEventListener eventListener : eventListeners) { - eventListener.selectHighestStat(HighestStat.DEF); - } - return true; - } - if (appraiseText.toLowerCase().contains(highest_stat_hp)) { - for (OnAppraisalEventListener eventListener : eventListeners) { - eventListener.selectHighestStat(HighestStat.STA); - } - return true; - } - return false; - } - - /** - * Selects the appropriate appraisalIVRangeGroup Checkbox depending on which phrase is matched. - * - * @param appraiseText the text to interpret. - * @return boolean returns true if the appraiseText matched a configured phrase. - */ - private boolean setIVRangeWith(String appraiseText) { - if (appraiseText.toLowerCase().contains(ivrange1_phrase1) - || (appraiseText.toLowerCase().contains(ivrange1_phrase2))) { - for (OnAppraisalEventListener eventListener : eventListeners) { - eventListener.selectIVSumRange(IVSumRange.RANGE_37_45); - } - return true; - } - if (appraiseText.toLowerCase().contains(ivrange2_phrase1) - || (appraiseText.toLowerCase().contains(ivrange2_phrase2))) { - for (OnAppraisalEventListener eventListener : eventListeners) { - eventListener.selectIVSumRange(IVSumRange.RANGE_30_36); - } - return true; - } - if (appraiseText.toLowerCase().contains(ivrange3_phrase1) - || (appraiseText.toLowerCase().contains(ivrange3_phrase2))) { - for (OnAppraisalEventListener eventListener : eventListeners) { - eventListener.selectIVSumRange(IVSumRange.RANGE_23_29); - } - return true; - } - if (appraiseText.toLowerCase().contains(ivrange4_phrase1) - || (appraiseText.toLowerCase().contains(ivrange4_phrase2))) { - for (OnAppraisalEventListener eventListener : eventListeners) { - eventListener.selectIVSumRange(IVSumRange.RANGE_0_22); - } - return true; - } - return false; } /** * The task which looks at the bottom of the screen, and adds any info it finds. This method then calls - * addInfoFromAppraiseText which performs the work of matching phrases to determine what should be checked. + * addStatScanResult which performs the work of matching phrases to determine what should be checked. */ private class ScreenScan implements Runnable { - @Override - public void run() { - Bitmap screen = screenGrabber.grabScreen(); - if (screen != null) { - String appraiseText = OcrHelper.getAppraisalText(settings, screen); - String hash = appraiseText.substring(0, appraiseText.indexOf("#")); - String text = appraiseText.substring(appraiseText.indexOf("#") + 1); - addInfoFromAppraiseText(text, hash); - } - } - } - public enum IVSumRange { - UNKNOWN(0, 45), - RANGE_0_22(0, 22), - RANGE_23_29(23, 29), - RANGE_30_36(30, 36), - RANGE_37_45(37, 45); + private static final int STAT_COUNT = 3; + private static final int ALLOWED_DISTANCE = 6; + private static final int COLOR_WHITE = 0xffFFFFFF; + private static final int COLOR_GRAY = 0xffE2E2E2; + private static final int COLOR_ORANGE = 0xffEE9219; + private static final int COLOR_RED = 0xffE18079; - public float minSum; - public float maxSum; + private static final float OFFSET_SPEECH_TOP = 0.16f; // 0.22f if the text has always at least two rows - IVSumRange(int minSum, float maxSum) { - this.minSum = minSum; - this.maxSum = maxSum; - } - } + private int barStart; + private float stepWidth; + private int barLength; + private int[] barCenter; - public enum HighestStat { - ATK, - DEF, - STA - } + // If this is null => initialize all variables on first scan, otherwise only do an update + private int[][] barData; + private int retries = 0; - public enum IVValueRange { - UNKNOWN(0, 15), - RANGE_0_7(0, 7), - RANGE_8_12(8, 12), - RANGE_13_14(13, 14), - RANGE_15(15, 15); + private int initialDelay; - public int minValue; - public int maxValue; + ScreenScan(int initialDelay) { + this.initialDelay = initialDelay; + } - IVValueRange(int minValue, int maxValue) { - this.minValue = minValue; - this.maxValue = maxValue; + void post() { + barData = null; + handler.removeCallbacks(this); + handler.postDelayed(this, initialDelay); } - } - public enum StatModifier { - EGG_OR_RAID(10), - WEATHER_BOOST(4); + private void initScreen(Bitmap screen) { + // Find top border of the speech bubble (scan to the left of the text to be sure that there is only white) + int offset = screen.getHeight() - pokefly.getCurrentNavigationBarHeight() - (int) ( + screen.getWidth() * OFFSET_SPEECH_TOP); + int x = (int) (screen.getWidth() * 0.04f); + int color; + do { + color = screen.getPixel(x, offset); + offset -= 2; // it is probably save to not scan EVERY pixel + } + while (color == COLOR_WHITE); + + Timber.d("Appraisal speech bubble top: %d", offset); + + this.barLength = (int) (screen.getWidth() * 0.33f); + // Prevent rounding errors, especially as it gets multiplied by 15 again later + this.stepWidth = screen.getWidth() / 15.0f * 0.33f; + this.barStart = (int) (screen.getWidth() * 0.136f); + + // We are at the top of the speech bubble, we can now just use the relative values from here + offset -= (int) (screen.getWidth() * 0.06f); // Offset should be now just below the first bar + this.barCenter = new int[STAT_COUNT]; + for (int i = STAT_COUNT - 1; i >= 0; i--) { + boolean inside = false; + int bottom = -1; + do { + color = screen.getPixel((int) (this.barStart + this.stepWidth), offset); + if (!inside && color != COLOR_WHITE) { + bottom = offset; + inside = true; + } + offset -= 1; + } + while ((color == COLOR_WHITE) ^ inside); + // offset = top y of bar, bottom = bottom y of bar + this.barCenter[i] = offset + (bottom - offset) / 2; + offset -= (int) (screen.getWidth() * 0.06f); + Timber.d("Appraisal stat bar #%d: x=%d, y=%d", i, barStart, this.barCenter[i]); + } - public int minStat; + this.barData = new int[3][this.barLength]; + } - StatModifier(int minStat) { - this.minStat = minStat; + @Override + public void run() { + Bitmap screen = screenGrabber.grabScreen(); + if (screen != null) { + if (barData == null) { + initScreen(screen); + } + + boolean change = false; + for (int i = this.barData.length - 1; i >= 0; i--) { + int[] buffer = new int[this.barLength]; + screen.getPixels(buffer, 0, this.barLength, this.barStart, this.barCenter[i], this.barLength, 1); + if (!Arrays.equals(buffer, this.barData[i])) { + Timber.d("Appraisal stat bar #%d has changed", i); + change = true; + this.barData[i] = buffer; + } + } + + if (change && retries < SCANRETRIES) { + handler.postDelayed(this, RETRYDELAY); + } else { + int[] width = new int[this.barData.length]; + // It scans them from the bottom to the top, so invert it either here to below in the creation + for (int i = 0; i < this.barData.length; i++) { + int color; + // The "do {} while" below loop increments it at least once + width[i] = -1; + do { + width[i]++; + color = this.barData[i][(int) (width[i] * this.stepWidth)]; + } + while (OcrHelper.isInColorRange(color , COLOR_ORANGE, ALLOWED_DISTANCE)); + + if (OcrHelper.isInColorRange(color , COLOR_RED, ALLOWED_DISTANCE)) { + width[i] = 15; + } else if (!OcrHelper.isInColorRange(color, COLOR_GRAY, ALLOWED_DISTANCE)) { + Timber.d("Invalid scan on bar #%d (color %08x)", i, color); + width = null; + break; + } + } + if (width == null) { + addStatScanResult(null); + } else { + addStatScanResult(new IVCombination(width[0], width[1], width[2])); + } + } + } } } public interface OnAppraisalEventListener { - void selectIVSumRange(IVSumRange range); - - void selectHighestStat(HighestStat stat); - - void selectIVValueRange(IVValueRange range); + void refreshSelection(); void highlightActiveUserInterface(); - - void resetActivatedUserInterface(); } } diff --git a/app/src/main/java/com/kamron/pogoiv/pokeflycomponents/fractions/AppraisalFraction.java b/app/src/main/java/com/kamron/pogoiv/pokeflycomponents/fractions/AppraisalFraction.java index 1ead90ef8..fa719bf5c 100644 --- a/app/src/main/java/com/kamron/pogoiv/pokeflycomponents/fractions/AppraisalFraction.java +++ b/app/src/main/java/com/kamron/pogoiv/pokeflycomponents/fractions/AppraisalFraction.java @@ -3,17 +3,18 @@ import android.content.SharedPreferences; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.constraint.ConstraintLayout; import android.util.DisplayMetrics; import android.view.MotionEvent; import android.view.View; +import android.widget.AdapterView; import android.widget.Button; import android.widget.CheckBox; import android.widget.LinearLayout; -import android.widget.RadioButton; -import android.widget.RadioGroup; -import android.widget.Switch; +import android.widget.SeekBar; -import com.kamron.pogoiv.GoIVSettings; +import android.widget.TextView; +import butterknife.OnCheckedChanged; import com.kamron.pogoiv.Pokefly; import com.kamron.pogoiv.R; import com.kamron.pogoiv.pokeflycomponents.AppraisalManager; @@ -25,7 +26,6 @@ import butterknife.BindView; import butterknife.ButterKnife; -import butterknife.OnCheckedChanged; import butterknife.OnClick; import butterknife.OnTouch; @@ -35,43 +35,6 @@ public class AppraisalFraction extends MovableFraction implements AppraisalManager.OnAppraisalEventListener, ReactiveColorListener { - @BindView(R.id.appraisalIVRangeGroup) - RadioGroup appraisalIVRangeGroup; - - @BindView(R.id.appraisalIVRange4) - RadioButton appraisalIVRange4; - @BindView(R.id.appraisalIVRange3) - RadioButton appraisalIVRange3; - @BindView(R.id.appraisalIVRange2) - RadioButton appraisalIVRange2; - @BindView(R.id.appraisalIVRange1) - RadioButton appraisalIVRange1; - - @BindView(R.id.attDefStaLayout) - LinearLayout attDefStaLayout; - - @BindView(R.id.attCheckbox) - CheckBox attCheckbox; - @BindView(R.id.defCheckbox) - CheckBox defCheckbox; - @BindView(R.id.staCheckbox) - CheckBox staCheckbox; - - @BindView(R.id.appraisalStatsGroup) - RadioGroup appraisalStatsGroup; - - @BindView(R.id.appraisalStat4) - RadioButton appraisalStat4; - @BindView(R.id.appraisalStat3) - RadioButton appraisalStat3; - @BindView(R.id.appraisalStat2) - RadioButton appraisalStat2; - @BindView(R.id.appraisalStat1) - RadioButton appraisalStat1; - - @BindView(R.id.eggRaidSwitch) - Switch eggRaidSwitch; - @BindView(R.id.btnCheckIv) Button btnCheckIv; @BindView(R.id.statsButton) @@ -80,9 +43,32 @@ public class AppraisalFraction extends MovableFraction implements AppraisalManag @BindView(R.id.headerAppraisal) LinearLayout headerAppraisal; + @BindView(R.id.valueLayout) + ConstraintLayout spinnerLayout; + + @BindView(R.id.atkEnabled) + CheckBox atkEnabled; + @BindView(R.id.atkSeek) + SeekBar atkSeek; + @BindView(R.id.atkValue) + TextView atkValue; + @BindView(R.id.defEnabled) + CheckBox defEnabled; + @BindView(R.id.defSeek) + SeekBar defSeek; + @BindView(R.id.defValue) + TextView defValue; + @BindView(R.id.staEnabled) + CheckBox staEnabled; + @BindView(R.id.staSeek) + SeekBar staSeek; + @BindView(R.id.staValue) + TextView staValue; + private Pokefly pokefly; private AppraisalManager appraisalManager; + private boolean insideUpdate = false; public AppraisalFraction(@NonNull Pokefly pokefly, @@ -107,55 +93,37 @@ public int getLayoutResId() { public void onCreate(@NonNull View rootView) { ButterKnife.bind(this, rootView); - // Restore any previously selected appraisal info - selectIVSumRange(appraisalManager.appraisalIVSumRange); - for (AppraisalManager.HighestStat highestStat : appraisalManager.highestStats) { - selectHighestStat(highestStat); - } - selectIVValueRange(appraisalManager.appraisalHighestStatValueRange); - for (AppraisalManager.StatModifier statModifier : appraisalManager.statModifiers) { - selectStatModifier(statModifier); - } + SeekBar.OnSeekBarChangeListener listener = new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + if (!insideUpdate) { + appraisalManager.attack = atkSeek.getProgress(); + appraisalManager.defense = defSeek.getProgress(); + appraisalManager.stamina = staSeek.getProgress(); + updateIVPreviewInButton(); + } + updateValueTexts(); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + // Nothing to do here + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + // Nothing to do here + } + }; + + atkSeek.setOnSeekBarChangeListener(listener); + defSeek.setOnSeekBarChangeListener(listener); + staSeek.setOnSeekBarChangeListener(listener); + setSpinnerSelection(); // Listen for new appraisal info appraisalManager.addOnAppraisalEventListener(this); - // Load the correct phrases from the text resources depending on what team is stored in app settings - switch (GoIVSettings.getInstance(pokefly).playerTeam()) { - case 0: // Mystic - appraisalIVRange4.setText(R.string.mv4); - appraisalIVRange3.setText(R.string.mv3); - appraisalIVRange2.setText(R.string.mv2); - appraisalIVRange1.setText(R.string.mv1); - appraisalStat1.setText(R.string.ms1); - appraisalStat2.setText(R.string.ms2); - appraisalStat3.setText(R.string.ms3); - appraisalStat4.setText(R.string.ms4); - break; - - case 1: // Valor - appraisalIVRange4.setText(R.string.vv4); - appraisalIVRange3.setText(R.string.vv3); - appraisalIVRange2.setText(R.string.vv2); - appraisalIVRange1.setText(R.string.vv1); - appraisalStat1.setText(R.string.vs1); - appraisalStat2.setText(R.string.vs2); - appraisalStat3.setText(R.string.vs3); - appraisalStat4.setText(R.string.vs4); - break; - - default: - case 2: // Instinct - appraisalIVRange4.setText(R.string.iv4); - appraisalIVRange3.setText(R.string.iv3); - appraisalIVRange2.setText(R.string.iv2); - appraisalIVRange1.setText(R.string.iv1); - appraisalStat1.setText(R.string.is1); - appraisalStat2.setText(R.string.is2); - appraisalStat3.setText(R.string.is3); - appraisalStat4.setText(R.string.is4); - break; - } GUIColorFromPokeType.getInstance().setListenTo(this); updateGuiColors(); } @@ -176,100 +144,12 @@ public int getDefaultVerticalOffset(DisplayMetrics displayMetrics) { return 0; } - @Override - public void selectIVSumRange(AppraisalManager.IVSumRange range) { - switch (range) { - case RANGE_37_45: - appraisalIVRange1.setChecked(true); - break; - case RANGE_30_36: - appraisalIVRange2.setChecked(true); - break; - case RANGE_23_29: - appraisalIVRange3.setChecked(true); - break; - case RANGE_0_22: - appraisalIVRange4.setChecked(true); - break; - default: - case UNKNOWN: - appraisalIVRangeGroup.clearCheck(); - break; - } - updateIVPreviewInButton(); - } - - @Override - public void selectHighestStat(AppraisalManager.HighestStat stat) { - switch (stat) { - case ATK: - attCheckbox.setChecked(true); - break; - case DEF: - defCheckbox.setChecked(true); - break; - case STA: - staCheckbox.setChecked(true); - break; - default: - break; - } - updateIVPreviewInButton(); - } - - @Override - public void selectIVValueRange(AppraisalManager.IVValueRange range) { - switch (range) { - case RANGE_15: - appraisalStat1.setChecked(true); - break; - case RANGE_13_14: - appraisalStat2.setChecked(true); - break; - case RANGE_8_12: - appraisalStat3.setChecked(true); - break; - case RANGE_0_7: - appraisalStat4.setChecked(true); - break; - default: - case UNKNOWN: - appraisalStatsGroup.clearCheck(); - break; - } - updateIVPreviewInButton(); - } - - private void selectStatModifier(AppraisalManager.StatModifier modifier) { - switch (modifier) { - case EGG_OR_RAID: - eggRaidSwitch.setChecked(true); - break; - case WEATHER_BOOST: - // TODO weatherSwitch.setChecked(true); - break; - default: - break; - } - updateIVPreviewInButton(); - } - /** * Sets the background for the appropriate checkbox group depending on where we are at in the appraisal process. */ @Override public void highlightActiveUserInterface() { - resetActivatedUserInterface(); - if (appraisalManager.appraisalIVSumRange == AppraisalManager.IVSumRange.UNKNOWN) { - // Percent range not completed yet - appraisalIVRangeGroup.setBackgroundResource(R.drawable.highlight_rectangle); - } else if (appraisalManager.appraisalHighestStatValueRange == AppraisalManager.IVValueRange.UNKNOWN) { - // Highest stat IV value range not completed yet - attDefStaLayout.setBackgroundResource(R.drawable.highlight_rectangle); - } else { - // Highest stat IV value range completed - appraisalStatsGroup.setBackgroundResource(R.drawable.highlight_rectangle); - } + spinnerLayout.setBackgroundResource(R.drawable.highlight_rectangle); } @@ -305,117 +185,47 @@ private void updateIVPreviewInButton() { } - /** - * Disables any background highlight that had previously been set. This method is used as a quick way to remove - * all backgrounds prior to setting again or when the auto appraisal process has completed. - */ - @Override - public void resetActivatedUserInterface() { - appraisalIVRangeGroup.setBackground(null); - attDefStaLayout.setBackground(null); - appraisalStatsGroup.setBackground(null); - } - - @OnTouch({R.id.positionHandler, R.id.additionalRefiningHeader}) - boolean positionHandlerTouchEvent(View v, MotionEvent event) { - return super.onTouch(v, event); - } - - @OnCheckedChanged(R.id.appraisalIVRange1) - void onIVRange1(boolean checked) { - if (checked) { - appraisalManager.appraisalIVSumRange = AppraisalManager.IVSumRange.RANGE_37_45; - } - } - - @OnCheckedChanged(R.id.appraisalIVRange2) - void onIVRange2(boolean checked) { - if (checked) { - appraisalManager.appraisalIVSumRange = AppraisalManager.IVSumRange.RANGE_30_36; - } - } - - @OnCheckedChanged(R.id.appraisalIVRange3) - void onIVRange3(boolean checked) { - if (checked) { - appraisalManager.appraisalIVSumRange = AppraisalManager.IVSumRange.RANGE_23_29; - } - } - - @OnCheckedChanged(R.id.appraisalIVRange4) - void onIVRange4(boolean checked) { - if (checked) { - appraisalManager.appraisalIVSumRange = AppraisalManager.IVSumRange.RANGE_0_22; - } - } - - @OnCheckedChanged(R.id.attCheckbox) - void attChecked(boolean checked) { - if (checked) { - appraisalManager.highestStats.add(AppraisalManager.HighestStat.ATK); - } else { - appraisalManager.highestStats.remove(AppraisalManager.HighestStat.ATK); - } - } - - @OnCheckedChanged(R.id.defCheckbox) - void defChecked(boolean checked) { - if (checked) { - appraisalManager.highestStats.add(AppraisalManager.HighestStat.DEF); - } else { - appraisalManager.highestStats.remove(AppraisalManager.HighestStat.DEF); - } - } - - @OnCheckedChanged(R.id.staCheckbox) - void staChecked(boolean checked) { - if (checked) { - appraisalManager.highestStats.add(AppraisalManager.HighestStat.STA); - } else { - appraisalManager.highestStats.remove(AppraisalManager.HighestStat.STA); - } - } - - @OnCheckedChanged(R.id.appraisalStat1) - void onStatRange1(boolean checked) { - if (checked) { - appraisalManager.appraisalHighestStatValueRange = AppraisalManager.IVValueRange.RANGE_15; + @OnCheckedChanged({R.id.atkEnabled, R.id.defEnabled, R.id.staEnabled}) + public void onEnabled() { + atkSeek.setEnabled(atkEnabled.isChecked()); + defSeek.setEnabled(defEnabled.isChecked()); + staSeek.setEnabled(staEnabled.isChecked()); + if (!insideUpdate) { + appraisalManager.attackValid = atkEnabled.isChecked(); + appraisalManager.defenseValid = defEnabled.isChecked(); + appraisalManager.staminaValid = staEnabled.isChecked(); } } - @OnCheckedChanged(R.id.appraisalStat2) - void onStatRange2(boolean checked) { - if (checked) { - appraisalManager.appraisalHighestStatValueRange = AppraisalManager.IVValueRange.RANGE_13_14; - } - } - - @OnCheckedChanged(R.id.appraisalStat3) - void onStatRange3(boolean checked) { - if (checked) { - appraisalManager.appraisalHighestStatValueRange = AppraisalManager.IVValueRange.RANGE_8_12; - } + @Override + public void refreshSelection() { + setSpinnerSelection(); + spinnerLayout.setBackground(null); + updateIVPreviewInButton(); } - @OnCheckedChanged(R.id.appraisalStat4) - void onStatRange4(boolean checked) { - if (checked) { - appraisalManager.appraisalHighestStatValueRange = AppraisalManager.IVValueRange.RANGE_0_7; - } + private void updateValueTexts() { + atkValue.setText(String.valueOf(appraisalManager.attack)); + defValue.setText(String.valueOf(appraisalManager.defense)); + staValue.setText(String.valueOf(appraisalManager.stamina)); } - @OnClick(R.id.eggRaidText) - void toggleRaidSwitch() { - eggRaidSwitch.toggle(); + private void setSpinnerSelection() { + insideUpdate = true; + updateValueTexts(); + atkSeek.setProgress(appraisalManager.attack); + defSeek.setProgress(appraisalManager.defense); + staSeek.setProgress(appraisalManager.stamina); + atkEnabled.setChecked(appraisalManager.attackValid); + defEnabled.setChecked(appraisalManager.defenseValid); + staEnabled.setChecked(appraisalManager.staminaValid); + onEnabled(); + insideUpdate = false; } - @OnCheckedChanged(R.id.eggRaidSwitch) - void onEggOrRaid(boolean checked) { - if (checked) { - appraisalManager.statModifiers.add(AppraisalManager.StatModifier.EGG_OR_RAID); - } else { - appraisalManager.statModifiers.remove(AppraisalManager.StatModifier.EGG_OR_RAID); - } + @OnTouch({R.id.positionHandler, R.id.additionalRefiningHeader}) + boolean positionHandlerTouchEvent(View v, MotionEvent event) { + return super.onTouch(v, event); } @OnClick({R.id.statsButton}) @@ -436,18 +246,6 @@ void checkIv() { @Override public void updateGuiColors() { int c = GUIColorFromPokeType.getInstance().getColor(); - /* appraisalIVRange4.setHighlightColor(GUIColorFromPokeType.getColor()); - appraisalIVRange3.setHighlightColor(GUIColorFromPokeType.getColor()); - appraisalIVRange2.setHighlightColor(GUIColorFromPokeType.getColor()); - appraisalIVRange1.setHighlightColor(GUIColorFromPokeType.getColor()); - appraisalStat1.setHighlightColor(GUIColorFromPokeType.getColor()); - appraisalStat2.setHighlightColor(GUIColorFromPokeType.getColor()); - appraisalStat3.setHighlightColor(GUIColorFromPokeType.getColor()); - appraisalStat4.setHighlightColor(GUIColorFromPokeType.getColor()); - attCheckbox.setHighlightColor(GUIColorFromPokeType.getColor()); - defCheckbox.setHighlightColor(GUIColorFromPokeType.getColor()); - staCheckbox.setHighlightColor(GUIColorFromPokeType.getColor());*/ - eggRaidSwitch.setHighlightColor(c); btnCheckIv.setBackgroundColor(c); statsButton.setBackgroundColor(c); headerAppraisal.setBackgroundColor(c); diff --git a/app/src/main/java/com/kamron/pogoiv/pokeflycomponents/ocrhelper/OcrHelper.java b/app/src/main/java/com/kamron/pogoiv/pokeflycomponents/ocrhelper/OcrHelper.java index a365bf522..5427b170c 100644 --- a/app/src/main/java/com/kamron/pogoiv/pokeflycomponents/ocrhelper/OcrHelper.java +++ b/app/src/main/java/com/kamron/pogoiv/pokeflycomponents/ocrhelper/OcrHelper.java @@ -16,6 +16,7 @@ import com.kamron.pogoiv.GoIVSettings; import com.kamron.pogoiv.Pokefly; import com.kamron.pogoiv.scanlogic.Data; +import com.kamron.pogoiv.scanlogic.IVCombination; import com.kamron.pogoiv.scanlogic.PokeInfoCalculator; import com.kamron.pogoiv.scanlogic.Pokemon; import com.kamron.pogoiv.scanlogic.ScanData; @@ -53,7 +54,6 @@ public class OcrHelper { private static TessBaseAPI tesseract = null; private static boolean isPokeSpamEnabled; private static LruCache ocrCache; - private static LruCache appraisalCache; private static int DEFAULT_FONT_COLOR = 4680814; //Pokemon go font color, rgb 71,108,110 (approximate) @@ -84,7 +84,6 @@ public static synchronized OcrHelper init(@NonNull Pokefly pokefly, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/-♀♂"); ocrCache = new LruCache<>(200); - appraisalCache = new LruCache<>(200); instance = new OcrHelper(); } @@ -94,11 +93,6 @@ public static synchronized OcrHelper init(@NonNull Pokefly pokefly, isPokeSpamEnabled = settings.isPokeSpamEnabled(); - Map appraisalMap = settings.loadAppraisalCache(); - for (Map.Entry entry : appraisalMap.entrySet()) { - appraisalCache.put(entry.getKey(), entry.getValue()); - } - return instance; } @@ -110,7 +104,6 @@ public void exit() { } instance = null; ocrCache = null; - appraisalCache = null; } /** @@ -400,7 +393,7 @@ private static Optional getPokemonEvolutionCostFromImg(@NonNull Bitmap * @param allowedDistance * @return */ - private static boolean isInColorRange(int inputColor, int matchWithColor, int allowedDistance){ + public static boolean isInColorRange(int inputColor, int matchWithColor, int allowedDistance) { int red = Color.red(inputColor); int green = Color.green(inputColor); int blue = Color.blue(inputColor); @@ -1275,48 +1268,6 @@ private static void ensureCorrectLevelArcSettings(@NonNull GoIVSettings settings } } - /** - * Reads the bottom part of the screen and returns the text there. - * - * @param screen The full phone screen. - * @return String of whats on the bottom of the screen. - */ - public static String getAppraisalText(@NonNull GoIVSettings settings, - @NonNull Bitmap screen) { - double appraisalBoxHeightFactor = 0.13; - double appraisalBoxStartYFactor = - (double) (screen.getHeight() - getNavigationBarHeight()) / screen.getHeight() - - appraisalBoxHeightFactor; - - Bitmap bottom = getImageCrop(screen, 0.05, appraisalBoxStartYFactor, 0.90, appraisalBoxHeightFactor); - String hash = "appraisal" + hashBitmap(bottom); - String appraisalText = appraisalCache.get(hash); - - if (appraisalText == null) { - //68,105,108 is the color of the appraisal text - //bottom = replaceColors(bottom, true, 68, 105, 108, Color.WHITE, 100, true); - tesseract.setImage(bottom); - //Set tesseract not single line mode - tesseract.setPageSegMode(TessBaseAPI.PageSegMode.PSM_SINGLE_BLOCK); - appraisalText = tesseract.getUTF8Text(); - appraisalCache.put(hash, appraisalText); - settings.saveAppraisalCache(appraisalCache.snapshot()); - } - - return hash + "#" + appraisalText; - - } - - /** - * Removes an entry from the ocrCache. - * - * @param hash The hash of the entry to remove. - */ - public static void removeEntryFromAppraisalCache(@NonNull GoIVSettings settings, @NonNull String hash) { - appraisalCache.remove(hash); - settings.saveAppraisalCache(appraisalCache.snapshot()); - } - private static int getNavigationBarHeight() { Pokefly pokefly = pokeflyRef.get(); if (pokefly != null) { diff --git a/app/src/main/java/com/kamron/pogoiv/scanlogic/ScanResult.java b/app/src/main/java/com/kamron/pogoiv/scanlogic/ScanResult.java index 24a1e1df8..a907a8de3 100644 --- a/app/src/main/java/com/kamron/pogoiv/scanlogic/ScanResult.java +++ b/app/src/main/java/com/kamron/pogoiv/scanlogic/ScanResult.java @@ -8,10 +8,8 @@ import com.kamron.pogoiv.utils.LevelRange; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Comparator; -import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; @@ -345,19 +343,21 @@ private void updateHighAndLowValues() { } public void refineWithAvailableInfoFrom(@NonNull AppraisalManager appraisalManager) { - refineByStatModifiers(appraisalManager.statModifiers); - refineByHighest(appraisalManager.highestStats); - refineByAppraisalPercentageRange(appraisalManager.appraisalIVSumRange); - refineByAppraisalIVRange(appraisalManager.appraisalHighestStatValueRange); + ArrayList refined = new ArrayList<>(iVCombinations.size()); - //Check if any appraisal has been done or if appraisal is uneccesary for the clipboard token. - if (appraisalManager.statModifiers.size() > 0 || appraisalManager.highestStats.size() > 0 || - appraisalManager.appraisalIVSumRange != AppraisalManager.IVSumRange.UNKNOWN - || appraisalManager.appraisalHighestStatValueRange != AppraisalManager.IVValueRange.UNKNOWN - || iVCombinations.size() ==1){ - hasBeenAppraiseRefined = true; + for (IVCombination combination : iVCombinations) { + if ((!appraisalManager.attackValid || combination.att == appraisalManager.attack) + && (!appraisalManager.defenseValid || combination.def == appraisalManager.defense) + && (!appraisalManager.staminaValid || combination.sta == appraisalManager.stamina)) { + refined.add(combination); + } } + iVCombinations = refined; + + //Check if any appraisal has been done or if appraisal is uneccesary for the clipboard token. + hasBeenAppraiseRefined = iVCombinations.size() == 1; + updateHighAndLowValues(); } private void selectScannedMoveset(@NonNull String moveFast, @NonNull String moveCharge) { @@ -375,95 +375,4 @@ private void selectScannedMoveset(@NonNull String moveFast, @NonNull String move } } - /** - * Removes all possible IV combinations where the boolean set to true stat isn't the highest. - * Several stats can be highest if they're equal. - */ - private void refineByHighest(@NonNull HashSet highestStats) { - if (highestStats.isEmpty()) { - return; - } - - Boolean[] knownAttDefSta = { - highestStats.contains(AppraisalManager.HighestStat.ATK), - highestStats.contains(AppraisalManager.HighestStat.DEF), - highestStats.contains(AppraisalManager.HighestStat.STA)}; - ArrayList refinedList = new ArrayList<>(); - for (IVCombination comb : iVCombinations) { - if (Arrays.equals(comb.getHighestStatSignature(), knownAttDefSta)) { - refinedList.add(comb); - } - } - iVCombinations = refinedList; - - updateHighAndLowValues(); - } - - /** - * Removes any iv combination that is outside the scope of the input percentage range. - * - * @param range IV percent range - */ - private void refineByAppraisalPercentageRange(AppraisalManager.IVSumRange range) { - if (range == AppraisalManager.IVSumRange.UNKNOWN) { - return; - } - - ArrayList refinedList = new ArrayList<>(); - for (IVCombination comb : iVCombinations) { - if (comb.getTotal() >= range.minSum && comb.getTotal() <= range.maxSum) { - refinedList.add(comb); - } - } - iVCombinations = refinedList; - - updateHighAndLowValues(); - } - - /** - * Removes any iv combination where the highest IV is outside the scope of he input range. - * - * @param range Range of the highest stat IV value - */ - private void refineByAppraisalIVRange(AppraisalManager.IVValueRange range) { - if (range == AppraisalManager.IVValueRange.UNKNOWN) { - return; - } - - ArrayList refinedList = new ArrayList<>(); - for (IVCombination comb : iVCombinations) { - if (comb.getHighestStat() >= range.minValue && comb.getHighestStat() <= range.maxValue) { - refinedList.add(comb); - } - } - iVCombinations = refinedList; - - updateHighAndLowValues(); - } - - /** - * Removes any combination that has stats that are lower than a certain amount. Egg and raid pokemon cannot have - * stats that are lower than 10, weather boosted can't be lower than 4. - */ - private void refineByStatModifiers(@NonNull HashSet statModifiers) { - if (statModifiers.isEmpty()) { - return; - } - - int minStat = 0; - for (AppraisalManager.StatModifier statModifier : statModifiers) { - minStat = Math.max(minStat, statModifier.minStat); - } - - ArrayList refinedList = new ArrayList<>(); - for (IVCombination comb : iVCombinations) { - if (comb.att >= minStat && comb.def >= minStat && comb.sta >= minStat) { - refinedList.add(comb); - } - } - iVCombinations = refinedList; - - updateHighAndLowValues(); - } - } diff --git a/app/src/main/res/layout/fraction_appraisal.xml b/app/src/main/res/layout/fraction_appraisal.xml index 4a0b3d96f..180d15421 100644 --- a/app/src/main/res/layout/fraction_appraisal.xml +++ b/app/src/main/res/layout/fraction_appraisal.xml @@ -71,219 +71,123 @@ - - - - - - - - - - - - - - + android:id="@+id/valueLayout" + android:layout_margin="4dp"> - - + + - + android:layout_marginEnd="8dp" + app:layout_constraintStart_toEndOf="@+id/atkHeader" + android:layout_marginStart="8dp" + app:layout_constraintBottom_toBottomOf="@+id/atkHeader" + app:layout_constraintTop_toTopOf="@+id/atkHeader" + android:max="15" + app:layout_constraintEnd_toStartOf="@+id/atkValue"/> + - - - - - - - - + + - - + - - + - - + + - - - - - - - + app:layout_constraintStart_toStartOf="@+id/defSeek" + android:layout_marginEnd="8dp" + app:layout_constraintTop_toTopOf="@+id/staHeader" + app:layout_constraintBottom_toBottomOf="@+id/staHeader" + android:max="15" + app:layout_constraintEnd_toStartOf="@+id/staValue"/> - - + android:id="@+id/staValue" + app:layout_constraintEnd_toEndOf="@+id/defValue" + app:layout_constraintBottom_toBottomOf="@+id/staSeek" + app:layout_constraintTop_toTopOf="@+id/staSeek" + android:textAlignment="textEnd" + tools:text="0"/> + - - angriff - verteidigung - kp - - erstaunlich - atemberaubendes - mir - aufgefallen - gutes - pokemon - wahrscheinlich - fortschritte - - berechnen - unglaublich - beeindruckt - werten - recht - beeindruckend - ganz - ganz - - total - alles - stark - stolz - ganz - gut - allzu - trotzdem - - hauen - wow - hervorragende - aufregend - schlechten - eltern - kampf - bringen - - allen - aufnehmen - stark - stark - ganz - gut - noch - verbessern - - besten - gesehen - hoch - hut - lassen - lassen - okay - okay - \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 429c79ba9..aa0cd4939 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -62,37 +62,5 @@ wurde nicht gefunden. Um Batterie zu sparen scanne Screenshots anstelle der automatischen Erkennung. Diese Einstellung muss für Android <= Kitak (4.4) verwendet werden Manuelles anpassen der Pokémon-Informationen bevor IV Berechnung erlauben - - - keine… Fortschr… - ein gutes Pokémon - wirklich aufgefall… - atember… Exemplar - insgesamt ganz okay - recht beeindr… - Werten …beeindr… - Unglaublich! - - - - mag es trotzdem - ganz gut! - sehr stark …stolz - total beeindr… - nicht viel bringen - schlechten Eltern! - Wie aufregend - WOW! - - - - noch verbess… - …ganz gut. - …wirklich stark! - mit allen aufneh… - …sind okay. - …sehen lassen - Hut ab! - die besten …gesehen diff --git a/app/src/main/res/values-es/appraisals.xml b/app/src/main/res/values-es/appraisals.xml deleted file mode 100644 index 0a60fc4db..000000000 --- a/app/src/main/res/values-es/appraisals.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - ataque - defensa - salud - maravilla - impresionante - llamado - ciertamente - encima - media - parece - lejos - - fuera - todo - realmente - impresionantes - bastante - bien - poco - desear - - simplemente - fascina - orgullo - sentir - bastante - bien - combate - gusta - - flipando - guau - excelentes - emocionante - cumplir - objetivo - utilidad - combate - - enfrentarse - mejores - realmente - fuerte - bastante - bien - algo - combates - - visto - pasada - fuertes - impresionante - buenas - duda - bien - supongo - \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index e1bcb8d8c..9f915328f 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -112,7 +112,7 @@ Muestra una vista previa de lo que se copia en el portapapeles en una pequeña ventana emergente Mostrar ventana emergente de la vista previa del portapapeles Retardar valoración automática - Tiempo de espera en el texto de valoración para finalizar. Los teléfonos de gama media pueden necesitar un retraso de 800 ms + Tiempo de espera en el texto de valoración para finalizar. Los teléfonos de gama media pueden necesitar un retraso de 4000 ms Mostrar previsualización del IV Muestra una pequeña ventana de vista previa en la ficha del Pokémon También previsualización portapapeles @@ -122,38 +122,6 @@ Modo GoIV Otras opciones - - no parece\nllegar lejos - por encima\nmedia - llamado\natención - maravilla\nvista - deja un…\nque desear - bastante\nbien - realmente\nimpres… - fuera cálc…\nincreib… - - - - no mejor\nen comb… - bastante\nbien - fuerte…\nque orgul… - simplemente\nme fascina - no serán\nmucha ut… - cumplir\nobjetivo… - excelentes\nemociona… - flipando\n¡GUAU! - - - - podría\nmejorar - bastante\nbien - realmente fuerte - enfrentar\na mejores - están bien\n…supongo - buenas\nsin duda - fuertes…\nimpresio… - lo mejor…\n¡Qué pas… - Conseguido de huevo o incursión Recalibrar Resultado calibración diff --git a/app/src/main/res/values-fr/appraisals.xml b/app/src/main/res/values-fr/appraisals.xml deleted file mode 100644 index 2003d9689..000000000 --- a/app/src/main/res/values-fr/appraisals.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - attaque - fense - pv - - merveille - captivant - toute mon - attention - rieur - moyenne - pas tr - loin - - passent - calculs - impressionn - vrai dire - liorent - vue - anormal - priori - - tonne beaucoup - tout faire - fort - fier - solide - solide - pas un - combattant - - estomaqu - bravo - excellentes - super - va faire des - va faire des - aideront pas - aideront pas - - tenir - aux meilleurs - vraiment - fort - est plut - est plut - peut devenir - meilleur combattant - - meilleures que - vues - super - super - quelques - bonnes - un peu - basiques - \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index eb4fceb04..d6b4c8720 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -91,37 +91,6 @@ Montre un aperçu de ce qui a été copié dans une petite fenêtre Montrer aperçu du presse-papier Délai d\'évaluation automatique - Combien de temps attendre pour que le texte d\'évaluation d\'un Pokémon ait fini d\'apparaître. Les téléphones bas de gamme pourraient demander un délai de 800 ms. - - - n\'ira pas\ntrès loin - supérieur à\nla moyenne - toute mon\nattention - merveille\ncaptivant - rien\nd\'anormal - s\'améliorent\n..vue d\'œil - je suis\nimpress.. - dépassent..\nmes calculs - - - pas un\ncombattant - Pokémon solide - fort..\nêtre fier - m\'étonne\nbeaucoup - aideront\npas.. - va faire\n..dégâts - excellentes\nsuper - estomaquée\nbravo - - - devenir\n..meilleur - plutôt bien - vraiment fort - tenir tête\n..meilleurs - un peu basiques - quelques bonnes stats - super élevées - meilleures\n..vues GoIV s\'est arrêtée diff --git a/app/src/main/res/values-it/appraisals.xml b/app/src/main/res/values-it/appraisals.xml deleted file mode 100644 index d3480ea41..000000000 --- a/app/src/main/res/values-it/appraisals.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - attacco - difesa - ps - - meraviglia - esemplare - attirato - attenzione - sopra - media - successo - lotte - - viste - incredibile - devo - eccellenti - piuttosto - buone - fuori - ordinario - - stupefacente - rivali - molto - orgoglioso - niente - male - potrebbe - piace - - sbalorditive - occhi - incredibili - incredibili - dovrebbero - bastare - saranno - aiuto - - sembra - potercela - molto - forte - malaccio - malaccio - potrebbe - migliorare - - dubbio - senza - incredibile - forti - qualcosa - valido - massimo - andare - \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index f3171be80..72aeeb351 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -70,42 +70,9 @@ - - non avrà\nsuccesso - sopra\nla media - attirato attenzione - meraviglia assoluta - ordinario - buone - eccellenti - incredibile - - - - mi piace\nlo stesso - niente male - forte orgoglioso - stupefa…\nno rivali - no grande aiuto - bastare\nnelle lotte - eccellenti forte - statistiche sbalorditive - - - - potrebbe migliorare - non è\nmalaccio - è molto\nforte - contro i\nmigliori - possono andare - qualcosa\ndi valido - forti\nincredibile - migliori…\nmai visto - - Riconoscimenti Caramelle - Quanto attendere che l\'animazione del testo di valutazione sia finita. Smartphone di fascia bassa potrebbero necessitare di 800ms. + Quanto attendere che l\'animazione del testo di valutazione sia finita. Smartphone di fascia bassa potrebbero necessitare di 4000ms. Attesa auto valutazione %s copiato negli appunti Anteprima diff --git a/app/src/main/res/values/appraisals.xml b/app/src/main/res/values/appraisals.xml deleted file mode 100644 index f6df0c8f6..000000000 --- a/app/src/main/res/values/appraisals.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - attack - defense - hp - - wonder - breathtaking - caught - attention - above - average - likely - headway - - calculations - incredible - impressed - must - noticeably - trending - norm - estimation - - amazes - accomplish - should - proud - decent - decent - great in - still - - blown - WOW - excellent - exciting - indicate - job - point - greatness - - battle - best of - is really - is really strong - pretty - decent - improvement - battling - - about - doubt - are really - impressive - definitely - good - right - basic - \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 74eaf2cee..0674fcd80 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -123,7 +123,7 @@ Show a preview of what is copied to the clipboard in a small popup Show clipboard preview popup Auto appraisal delay - How long to wait for the appraisal text animation to end. Budget phones might need a 800 ms delay. + How long to wait for the appraisal animations to end. Budget phones might need a 4000 ms delay. Show quick IV preview Display a small preview automatically when on a \'mon screen Also preview clipboard @@ -323,4 +323,5 @@ "Save \n& exit" fastCopyToClipboard Copy to clipboard on preview + Unset diff --git a/app/src/main/res/xml/settings.xml b/app/src/main/res/xml/settings.xml index dfd3ef30a..d4c6e85ee 100644 --- a/app/src/main/res/xml/settings.xml +++ b/app/src/main/res/xml/settings.xml @@ -75,13 +75,13 @@ android:title="@string/pokespam_setting_title"/>