diff --git a/PokemonGo-UWP/App.xaml b/PokemonGo-UWP/App.xaml index 0caddbc90..7a2fe5464 100644 --- a/PokemonGo-UWP/App.xaml +++ b/PokemonGo-UWP/App.xaml @@ -70,7 +70,7 @@ - + @@ -95,6 +95,7 @@ + diff --git a/PokemonGo-UWP/App.xaml.cs b/PokemonGo-UWP/App.xaml.cs index 54fdf40f2..2328e092f 100644 --- a/PokemonGo-UWP/App.xaml.cs +++ b/PokemonGo-UWP/App.xaml.cs @@ -310,7 +310,8 @@ public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs } else if (latestUpdateInfo.Status == UpdateManager.UpdateStatus.NextVersionNotReady) { - var dialog = new MessageDialog("Please wait on next update", "This version is obsolete"); + var dialog = new MessageDialog("We've temporarily disabled the app to protect your account. An update will be ready soon. " + + "Please DO NOT open an issue on GitHub. Thank you for your patience."); dialog.Commands.Add(new UICommand("OK")); dialog.DefaultCommandIndex = 0; dialog.CancelCommandIndex = 1; diff --git a/PokemonGo-UWP/Assets/Icons/spawnpoint.png b/PokemonGo-UWP/Assets/Icons/spawnpoint.png new file mode 100644 index 000000000..35f2c9cea Binary files /dev/null and b/PokemonGo-UWP/Assets/Icons/spawnpoint.png differ diff --git a/PokemonGo-UWP/Assets/UI/ash_withincense.png b/PokemonGo-UWP/Assets/UI/ash_withincense.png new file mode 100644 index 000000000..d6ba85bf2 Binary files /dev/null and b/PokemonGo-UWP/Assets/UI/ash_withincense.png differ diff --git a/PokemonGo-UWP/Controls/CircularProgressBar.xaml.cs b/PokemonGo-UWP/Controls/CircularProgressBar.xaml.cs index 4381cabfd..4d4ea8c01 100644 --- a/PokemonGo-UWP/Controls/CircularProgressBar.xaml.cs +++ b/PokemonGo-UWP/Controls/CircularProgressBar.xaml.cs @@ -38,14 +38,10 @@ private static void OnPropertyChanged(DependencyObject sender, DependencyPropert private static void OnImageSourcePathChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) { + if (sender == null) return; CircularProgressBar circularProgressBar = sender as CircularProgressBar; - if (circularProgressBar?.ImageSourcePath != null) - { - circularProgressBar.InnerPathRoot.Fill = new ImageBrush - { - ImageSource = circularProgressBar.ImageSourcePath - }; - } + BitmapImage fillImg = (circularProgressBar.ImageSourcePath != null) ?new BitmapImage(circularProgressBar.ImageSourcePath) : new BitmapImage(); + circularProgressBar.InnerPathRoot.Fill = new ImageBrush { ImageSource = fillImg }; } #endregion @@ -68,7 +64,7 @@ private static void OnImageSourcePathChanged(DependencyObject sender, Dependency public static readonly DependencyProperty InnerSegmentColorProperty = DependencyProperty.Register("InnerSegmentColor", typeof(Brush), typeof(CircularProgressBar), new PropertyMetadata(Colors.Gray)); - public static readonly DependencyProperty ImageSourcePathProperty = DependencyProperty.Register("ImageSourcePath", typeof(BitmapImage), typeof(CircularProgressBar), new PropertyMetadata("", OnImageSourcePathChanged)); + public static readonly DependencyProperty ImageSourcePathProperty = DependencyProperty.Register("ImageSourcePath", typeof(Uri), typeof(CircularProgressBar), new PropertyMetadata("", OnImageSourcePathChanged)); #endregion @@ -122,9 +118,9 @@ public Brush InnerSegmentColor set { SetValue(InnerSegmentColorProperty, value); } } - public BitmapImage ImageSourcePath + public Uri ImageSourcePath { - get { return (BitmapImage)GetValue(ImageSourcePathProperty); } + get { return (Uri)GetValue(ImageSourcePathProperty); } set { SetValue(ImageSourcePathProperty, value); } } #endregion diff --git a/PokemonGo-UWP/Entities/AppliedItemWrapper.cs b/PokemonGo-UWP/Entities/AppliedItemWrapper.cs index 2fd3697af..8d8b2bd83 100644 --- a/PokemonGo-UWP/Entities/AppliedItemWrapper.cs +++ b/PokemonGo-UWP/Entities/AppliedItemWrapper.cs @@ -107,4 +107,4 @@ protected virtual void OnPropertyChanged(string propertyName) #endregion } -} \ No newline at end of file +} diff --git a/PokemonGo-UWP/Entities/IncensePokemon.cs b/PokemonGo-UWP/Entities/IncensePokemon.cs new file mode 100644 index 000000000..65b6699b0 --- /dev/null +++ b/PokemonGo-UWP/Entities/IncensePokemon.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.Devices.Geolocation; +using Windows.Foundation; +using Newtonsoft.Json; +using PokemonGo_UWP.Utils; +using PokemonGo_UWP.Utils.Helpers; +using PokemonGo_UWP.Views; +using POGOProtos.Enums; +using POGOProtos.Map.Fort; +using Template10.Common; +using Template10.Mvvm; +using POGOProtos.Networking.Responses; + +namespace PokemonGo_UWP.Entities +{ + public class IncensePokemon : IMapPokemon + { + /// + /// Infos on the current lured Pokemon + /// + [JsonProperty, JsonConverter(typeof(ProtobufJsonNetConverter))] + private GetIncensePokemonResponse _incensePokemonResponse; + + public Point Anchor => new Point(0.5, 1); + + public IncensePokemon(GetIncensePokemonResponse incensePokemonResponse, double lat, double lng) + { + _incensePokemonResponse = incensePokemonResponse; + Geoposition = new Geopoint(GetLocation(lat, lng, 1)); + } + + public void Update(IMapPokemon update) + { + var incense = (IncensePokemon)update; + + _incensePokemonResponse = incense._incensePokemonResponse; + Geoposition = incense.Geoposition; + + OnPropertyChanged(nameof(PokemonId)); + OnPropertyChanged(nameof(EncounterId)); + OnPropertyChanged(nameof(SpawnpointId)); + OnPropertyChanged(nameof(Geoposition)); + } + + #region Wrapped Properties + + public PokemonId PokemonId => _incensePokemonResponse.PokemonId; + + public ulong EncounterId => _incensePokemonResponse.EncounterId; + + public string SpawnpointId => _incensePokemonResponse.EncounterLocation; + + public Geopoint Geoposition { get; set; } + + #endregion + + private DelegateCommand _tryCatchPokemon; + + /// + /// We're just navigating to the capture page, reporting that the player wants to capture the selected Pokemon. + /// + public DelegateCommand TryCatchPokemon => _tryCatchPokemon ?? ( + _tryCatchPokemon = new DelegateCommand(() => + { + NavigationHelper.NavigationState["CurrentPokemon"] = this; + // Disable map update + GameClient.ToggleUpdateTimer(false); + BootStrapper.Current.NavigationService.Navigate(typeof(CapturePokemonPage)); + }, () => true) + ); + + private BasicGeoposition GetLocation(double x0, double y0, int radius) + { + var random = new Random(); + + // Convert radius from meters to degrees + double radiusInDegrees = radius / 111000f; + + var u = random.NextDouble(); + var v = random.NextDouble(); + var w = radiusInDegrees * Math.Sqrt(u); + var t = 2 * Math.PI * v; + var x = w * Math.Cos(t); + var y = w * Math.Sin(t); + + // Adjust the x-coordinate for the shrinking of the east-west distances + var new_x = x / Math.Cos(y0); + + var foundLatitude = new_x + x0; + var foundLongitude = y + y0; + return new BasicGeoposition { Latitude = foundLatitude, Longitude = foundLongitude }; + } + + #region INotifyPropertyChanged + + public event PropertyChangedEventHandler PropertyChanged; + + protected virtual void OnPropertyChanged(string propertyName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + #endregion + } +} diff --git a/PokemonGo-UWP/Entities/SpawnPointWrapper.cs b/PokemonGo-UWP/Entities/SpawnPointWrapper.cs new file mode 100644 index 000000000..851c20694 --- /dev/null +++ b/PokemonGo-UWP/Entities/SpawnPointWrapper.cs @@ -0,0 +1,60 @@ +using System.ComponentModel; +using Newtonsoft.Json; +using PokemonGo_UWP.Utils.Helpers; +using POGOProtos.Map; +using Windows.Devices.Geolocation; +using Windows.Foundation; + +namespace PokemonGo_UWP.Entities +{ + /// + /// We need to wrap this so we can reduce the number of ui updates. + /// + public class SpawnPointWrapper : IUpdatable, INotifyPropertyChanged + { + [JsonProperty, JsonConverter(typeof(ProtobufJsonNetConverter))] + private SpawnPoint _spawnPoint; + + public Point Anchor => new Point(0.5, 1); + + public SpawnPointWrapper(SpawnPoint spawnPoint) + { + _spawnPoint = spawnPoint; + Geoposition = + new Geopoint(new BasicGeoposition { Latitude = _spawnPoint.Latitude, Longitude = _spawnPoint.Longitude }); + } + + /// + /// The file name for spawnpoint, located in /Assets/Icons + /// + public string ImageFileName => "spawnpoint.png"; + + /// + /// The file name for spawnpoint, located in /Assets/Icons + /// + public string ImageFilePath => $"ms-appx:///Assets/Icons/spawnpoint.png"; + + public void Update(SpawnPoint update) + { + _spawnPoint = update; + } + + #region Wrapped Properties + + //public float DistanceInMeters => _spawnPoint.DistanceInMeters; + public Geopoint Geoposition { get; set; } + + #endregion + + #region INotifyPropertyChanged + + public event PropertyChangedEventHandler PropertyChanged; + + protected virtual void OnPropertyChanged(string propertyName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + #endregion + } +} diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.cs.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.cs.xlf index bfd5a85b0..2f2481768 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.cs.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.cs.xlf @@ -558,6 +558,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. Empty module slot Empty module slot + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.da.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.da.xlf index 10df2efc7..b9e2ffa1d 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.da.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.da.xlf @@ -694,6 +694,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.de-CH.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.de-CH.xlf index afb189d96..65b211c54 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.de-CH.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.de-CH.xlf @@ -619,6 +619,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.de.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.de.xlf index 09000172b..b87a9ba50 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.de.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.de.xlf @@ -556,6 +556,10 @@ Du hast auch {1} Sternenstaub, {2} Bonbon und {3} EP erhalten. Noch {0} × If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.el.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.el.xlf index 0abfb536a..f68426bee 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.el.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.el.xlf @@ -558,6 +558,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.en-GB.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.en-GB.xlf index 276fb20e9..bc24068bb 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.en-GB.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.en-GB.xlf @@ -1880,6 +1880,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.es-MX.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.es-MX.xlf index 5b3cddf12..72ea1515a 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.es-MX.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.es-MX.xlf @@ -1880,6 +1880,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.es.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.es.xlf index 0ca3c8721..c84d77fa3 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.es.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.es.xlf @@ -558,6 +558,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.fi.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.fi.xlf index 822ebb066..cf2dd3dc9 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.fi.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.fi.xlf @@ -538,6 +538,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.fr.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.fr.xlf index d56d55a74..982710dd5 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.fr.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.fr.xlf @@ -561,6 +561,10 @@ Tu as aussi reçu {1} Poudre d'étoile, {2} Bonbon et {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.he.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.he.xlf index cb5b649ca..325b472ab 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.he.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.he.xlf @@ -1881,6 +1881,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.hr-HR.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.hr-HR.xlf index a672cb7ae..99e4b969e 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.hr-HR.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.hr-HR.xlf @@ -1141,6 +1141,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.hr.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.hr.xlf index b05e253a3..2554c90da 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.hr.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.hr.xlf @@ -1141,6 +1141,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.hu.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.hu.xlf index d799081f6..44383e316 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.hu.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.hu.xlf @@ -569,6 +569,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.id.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.id.xlf index e3cc37349..4d408b706 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.id.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.id.xlf @@ -554,6 +554,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.it.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.it.xlf index fd5b44daa..286990fc1 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.it.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.it.xlf @@ -558,6 +558,10 @@ Hai ottenuto anche {1} Polvere di stella, {2} Caramelle e {3} PE. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.ja.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.ja.xlf index ad969dafc..1f3d27bc1 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.ja.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.ja.xlf @@ -554,6 +554,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.nb-NO.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.nb-NO.xlf index ff4ac412b..cb249d34a 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.nb-NO.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.nb-NO.xlf @@ -1147,6 +1147,10 @@ Du fikk også {1} Stjernestøv, {2} Candy og {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.nl.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.nl.xlf index 2f862cd6c..6105d9cf6 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.nl.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.nl.xlf @@ -557,6 +557,10 @@ Je hebt ook {1} Stardust, {2} Candy en {3} XP gekregen. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.pl.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.pl.xlf index d8734d92f..15a0bb71e 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.pl.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.pl.xlf @@ -556,6 +556,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.pt-BR.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.pt-BR.xlf index b1da68bb9..2d454ec1c 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.pt-BR.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.pt-BR.xlf @@ -559,6 +559,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.pt-PT.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.pt-PT.xlf index f277863c9..f052fc6ef 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.pt-PT.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.pt-PT.xlf @@ -557,6 +557,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.ru.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.ru.xlf index 464d8f00a..9c62c8cab 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.ru.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.ru.xlf @@ -559,6 +559,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.sk.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.sk.xlf index e5819ca0c..0f574c650 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.sk.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.sk.xlf @@ -554,6 +554,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.tr.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.tr.xlf index 13d1a34d3..0b5c4c264 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.tr.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.tr.xlf @@ -556,6 +556,10 @@ Aynı zamanda {1} Stardust, {2} Şeker ve {3} XP kazandın. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.zh-CN.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.zh-CN.xlf index 9f91e0f48..9bde6e302 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.zh-CN.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.zh-CN.xlf @@ -558,6 +558,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.zh-HK.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.zh-HK.xlf index 0bb1a2e08..0be7f3a68 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.zh-HK.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.zh-HK.xlf @@ -1064,6 +1064,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.zh-TW.xlf b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.zh-TW.xlf index a2d159d29..d8365e821 100644 --- a/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.zh-TW.xlf +++ b/PokemonGo-UWP/MultilingualResources/PokemonGo-UWP.zh-TW.xlf @@ -326,6 +326,10 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + Use {0} ? + diff --git a/PokemonGo-UWP/PokemonGo-UWP.csproj b/PokemonGo-UWP/PokemonGo-UWP.csproj index e8f322ea6..7a70bc9ba 100644 --- a/PokemonGo-UWP/PokemonGo-UWP.csproj +++ b/PokemonGo-UWP/PokemonGo-UWP.csproj @@ -247,6 +247,7 @@ + @@ -322,6 +323,7 @@ + @@ -767,8 +769,11 @@ + + + diff --git a/PokemonGo-UWP/Strings/en-US/CodeResources.resw b/PokemonGo-UWP/Strings/en-US/CodeResources.resw index 012c2e7f3..fed6c1c62 100644 --- a/PokemonGo-UWP/Strings/en-US/CodeResources.resw +++ b/PokemonGo-UWP/Strings/en-US/CodeResources.resw @@ -353,4 +353,7 @@ You also got {1} Stardust, {2} Candy and {3} XP. {0} use(s) left If your language uses multiply sign, use × (unicode char) and not x + + Use {0} ? + \ No newline at end of file diff --git a/PokemonGo-UWP/Strings/en-US/Resources.resw b/PokemonGo-UWP/Strings/en-US/Resources.resw index 834c2aa1c..d4f646618 100644 --- a/PokemonGo-UWP/Strings/en-US/Resources.resw +++ b/PokemonGo-UWP/Strings/en-US/Resources.resw @@ -130,7 +130,7 @@ LOGIN with PTC Account - To login, enter your Username/Email and Password above. If you don't trust this app, please close it now. Niantic may ban you for using this app. Use at your own risk. + WARNING: Niantic may ban you for using this app. Use at your own risk. If you don't trust this app, please close it now. nearby diff --git a/PokemonGo-UWP/Styles/Custom.xaml b/PokemonGo-UWP/Styles/Custom.xaml index e9bb3fef6..86771aaaf 100644 --- a/PokemonGo-UWP/Styles/Custom.xaml +++ b/PokemonGo-UWP/Styles/Custom.xaml @@ -1,6 +1,7 @@  @@ -977,6 +978,16 @@ + + + + + @@ -1067,6 +1092,17 @@ + + @@ -1116,7 +1152,7 @@ - + @@ -1151,7 +1187,7 @@ - + @@ -1253,6 +1289,23 @@ + + + diff --git a/PokemonGo-UWP/Utils/Game/Converters.cs b/PokemonGo-UWP/Utils/Game/Converters.cs index 686930743..9b299ecba 100644 --- a/PokemonGo-UWP/Utils/Game/Converters.cs +++ b/PokemonGo-UWP/Utils/Game/Converters.cs @@ -256,7 +256,7 @@ public class PokemonToStardustForPowerUpForegroundConverter : IValueConverter public object Convert(object value, Type targetType, object parameter, string language) { - var startustToPowerUp = System.Convert.ToInt32(GameClient.PokemonUpgradeSettings.StardustCost[ + var startustToPowerUp = System.Convert.ToInt32(GameClient.PokemonUpgradeSettings.StardustCost[ System.Convert.ToInt32(Math.Floor(PokemonInfo.GetLevel(((PokemonDataWrapper)value).WrappedData)) - 1)]); return startustToPowerUp > GameClient.PlayerProfile.Currencies.FirstOrDefault(item => item.Name.Equals("STARDUST")).Amount ? new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)) : App.Current.Resources["TitleTextColor"]; } @@ -332,9 +332,9 @@ public class PokemonToCandiesForEvolveForegroundConverter : IValueConverter public object Convert(object value, Type targetType, object parameter, string language) { - if (value == null) return new SolidColorBrush(Color.FromArgb(0,0,0,0)); + if (value == null) return new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)); var extraData = GameClient.GetExtraDataForPokemon(((PokemonDataWrapper)value).PokemonId); - return extraData.CandyToEvolve > GameClient.CandyInventory.FirstOrDefault(item => item.FamilyId == extraData.FamilyId).Candy_ ? new SolidColorBrush(Color.FromArgb(255,255,0,0)) : App.Current.Resources["TitleTextColor"]; + return extraData.CandyToEvolve > GameClient.CandyInventory.FirstOrDefault(item => item.FamilyId == extraData.FamilyId).Candy_ ? new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)) : App.Current.Resources["TitleTextColor"]; } public object ConvertBack(object value, Type targetType, object parameter, string language) @@ -389,10 +389,11 @@ public class PokemonToTranslatedPokemonTypeConverter : IValueConverter public object Convert(object value, Type targetType, object parameter, string language) { PokemonType pokeType; - if(System.Convert.ToInt32(parameter) == 2) + if (System.Convert.ToInt32(parameter) == 2) { pokeType = GameClient.GetExtraDataForPokemon(((PokemonDataWrapper)value).PokemonId).Type2; - } else + } + else { pokeType = GameClient.GetExtraDataForPokemon(((PokemonDataWrapper)value).PokemonId).Type; } @@ -416,11 +417,12 @@ public object Convert(object value, Type targetType, object parameter, string la if (value == null) return Visibility.Collapsed; Visibility visibility = Visibility.Collapsed; - if(System.Convert.ToBoolean(parameter)) + if (System.Convert.ToBoolean(parameter)) { visibility = (Visibility)new InverseVisibleWhenTypeIsNotNoneConverter() .Convert(GameClient.GetExtraDataForPokemon(((PokemonDataWrapper)value).PokemonId).Type2, targetType, null, language); - } else + } + else { visibility = (Visibility)new VisibleWhenTypeIsNotNoneConverter() .Convert(GameClient.GetExtraDataForPokemon(((PokemonDataWrapper)value).PokemonId).Type2, targetType, null, language); @@ -564,7 +566,7 @@ public class PokemonCaptureCellToLocationConverter : IValueConverter public object Convert(object value, Type targetType, object parameter, string language) { - if(value == null || !(value is ulong)) + if (value == null || !(value is ulong)) { return ""; } @@ -575,11 +577,12 @@ public object Convert(object value, Type targetType, object parameter, string la var cellCenter = new S2CellId((ulong)value).ChildEndForLevel(30).ToLatLng(); MapLocationFinderResult result = await MapLocationFinder.FindLocationsAtAsync(new Geopoint(new BasicGeoposition() { Latitude = cellCenter.LatDegrees, Longitude = cellCenter.LngDegrees })); - if(result.Status == MapLocationFinderStatus.Success && result.Locations.Count != 0) + if (result.Status == MapLocationFinderStatus.Success && result.Locations.Count != 0) { var captureLocation = result.Locations[0]; return $"{captureLocation.Address.Town}, {captureLocation.Address.Region}, {captureLocation.Address.Country}"; - } else + } + else { return ""; } @@ -608,15 +611,16 @@ public object Convert(object value, Type targetType, object parameter, string la PokemonDataWrapper pokemon = (PokemonDataWrapper)value; Image img = new Image(); - if(pokemon.IsBuddy) + if (pokemon.IsBuddy) { // Buddy img.Source = new BitmapImage(new Uri("ms-appx:///assets/Icons/ic_buddy.png")); img.Margin = detailView ? new Thickness(9) : new Thickness(3); - } else + } + else { // ArenaDeployment - switch(GameClient.PlayerProfile.Team) + switch (GameClient.PlayerProfile.Team) { case TeamColor.Red: img.Source = new BitmapImage(new Uri("ms-appx:///assets/Icons/ic_arena_red.png")); @@ -766,8 +770,9 @@ public class ItemToItemIconConverter : IValueConverter public object Convert(object value, Type targetType, object parameter, string language) { - var itemId = (value as ItemAward)?.ItemId ?? ((value as ItemData)?.ItemId ?? ((ItemDataWrapper)value).ItemId); - return new Uri($"ms-appx:///Assets/Items/Item_{(int)itemId}.png"); + var itemId = (value as ItemAward)?.ItemId ?? ((value as ItemData)?.ItemId ?? ((value as ItemDataWrapper)?.ItemId ?? ((AppliedItemWrapper)value).ItemId)); + + return new Uri($"ms-appx:///Assets/Items/Item_{(int)itemId}.png"); } public object ConvertBack(object value, Type targetType, object parameter, string language) @@ -873,7 +878,7 @@ public object ConvertBack(object value, Type targetType, object parameter, strin #endregion } - public class AchievementValueToMedalImageConverter : IValueConverter + public class AchievementValueToMedalIconConverter : IValueConverter { #region Implementation of IValueConverter @@ -888,11 +893,11 @@ public object Convert(object value, Type targetType, object parameter, string la int level = 3; if (achievement.Value == null) { - return new BitmapImage(new Uri("ms-appx:///Assets/Achievements/badge_lv0.png")); + return new Uri("ms-appx:///Assets/Achievements/badge_lv0.png"); } if (float.Parse(achievement.Value.ToString()) < float.Parse(bronze.Value.ToString())) { - return new BitmapImage(new Uri("ms-appx:///Assets/Achievements/badge_lv0.png")); + return new Uri("ms-appx:///Assets/Achievements/badge_lv0.png"); } if (float.Parse(achievement.Value.ToString()) < float.Parse(gold.Value.ToString())) { @@ -916,9 +921,9 @@ public object Convert(object value, Type targetType, object parameter, string la case "pikachufan": case "scientist": case "youngster": - return new BitmapImage(new Uri("ms-appx:///Assets/Achievements/" + achievement.Key.ToString().ToLower().Replace(" ", "") + "_lv" + level.ToString() + ".png")); + return new Uri("ms-appx:///Assets/Achievements/" + achievement.Key.ToString().ToLower().Replace(" ", "") + "_lv" + level.ToString() + ".png"); default: - return new BitmapImage(new Uri("ms-appx:///Assets/Achievements/badge_lv" + level.ToString() + ".png")); + return new Uri("ms-appx:///Assets/Achievements/badge_lv" + level.ToString() + ".png"); } } @@ -1187,7 +1192,8 @@ public class ItemToItemNameConverter : IValueConverter public object Convert(object value, Type targetType, object parameter, string language) { - var itemId = (value as ItemAward)?.ItemId ?? ((value as ItemData)?.ItemId ?? ((ItemDataWrapper)value).ItemId); + var itemId = (value as ItemAward)?.ItemId ?? ((value as ItemData)?.ItemId ?? ((value as ItemDataWrapper)?.ItemId ?? ((AppliedItemWrapper)value).ItemId)); + return Resources.Items.GetString(itemId.ToString()); } @@ -1205,7 +1211,8 @@ public class ItemToItemDescriptionConverter : IValueConverter public object Convert(object value, Type targetType, object parameter, string language) { - var itemId = (value as ItemAward)?.ItemId ?? ((value as ItemData)?.ItemId ?? ((ItemDataWrapper)value).ItemId); + var itemId = (value as ItemAward)?.ItemId ?? ((value as ItemData)?.ItemId ?? ((value as ItemDataWrapper)?.ItemId ?? ((AppliedItemWrapper)value).ItemId)); + return Resources.Items.GetString("D_" + itemId); } @@ -1223,8 +1230,9 @@ public class ItemToItemRecycleVisibilityConverter : IValueConverter public object Convert(object value, Type targetType, object parameter, string language) { - var itemId = (value as ItemAward)?.ItemId ?? ((value as ItemData)?.ItemId ?? ((ItemDataWrapper)value).ItemId); - switch(itemId) + var itemId = (value as ItemAward)?.ItemId ?? ((value as ItemData)?.ItemId ?? ((value as ItemDataWrapper)?.ItemId ?? ((AppliedItemWrapper)value).ItemId)); + + switch (itemId) { case ItemId.ItemUnknown: case ItemId.ItemSpecialCamera: @@ -1263,8 +1271,11 @@ public ViewModels.ItemsInventoryPageViewModel.ItemsInventoryViewMode CurrentView public object Convert(object value, Type targetType, object parameter, string language) { if (!(value is ItemDataWrapper)) return 1; - + var useableList = CurrentViewMode == ViewModels.ItemsInventoryPageViewModel.ItemsInventoryViewMode.Normal ? GameClient.NormalUseItemIds : GameClient.CatchItemIds; + var appliedList = GameClient.AppliedItems.Select(x => x.ItemId); + useableList.RemoveAll(x => appliedList.Contains(x)); + return useableList.Contains(((ItemDataWrapper)value).ItemId) ? 1 : 0.5; } @@ -1750,7 +1761,7 @@ public object Convert(object value, Type targetType, object parameter, string la { bool invert = false; Boolean.TryParse((string)parameter, out invert); - + if ((((EggIncubator)value).ItemId == ItemId.ItemIncubatorBasicUnlimited) ^ invert) { return Visibility.Visible; @@ -1950,41 +1961,51 @@ public object ConvertBack(object value, Type targetType, object parameter, strin #endregion } - public class IntToBooleanConverter : IValueConverter { + public class IntToBooleanConverter : IValueConverter + { #region Implementation of IValueConverter - public object Convert(object value, Type targetType, object parameter, string language) { + public object Convert(object value, Type targetType, object parameter, string language) + { return value.Equals(1); } - public object ConvertBack(object value, Type targetType, object parameter, string language) { + public object ConvertBack(object value, Type targetType, object parameter, string language) + { throw new NotImplementedException(); } #endregion } - public class PokemonLastHoursVisibiltyConverter : IValueConverter { - + public class PokemonLastHoursVisibiltyConverter : IValueConverter + { + #region Implementation of IValueConverter - public object Convert(object value, Type targetType, object parameter, string language) { - if(value == null) { + public object Convert(object value, Type targetType, object parameter, string language) + { + if (value == null) + { return Visibility.Collapsed; } var ms = System.Convert.ToUInt64(value); var creationDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Local); creationDate = creationDate.Add(TimeSpan.FromMilliseconds(ms)); var now = DateTime.Now; - if (now.AddDays(-1) <= creationDate) { + if (now.AddDays(-1) <= creationDate) + { return Visibility.Visible; - } else { + } + else + { return Visibility.Collapsed; } } - public object ConvertBack(object value, Type targetType, object parameter, string language) { + public object ConvertBack(object value, Type targetType, object parameter, string language) + { throw new NotImplementedException(); } @@ -2048,7 +2069,7 @@ public object Convert(object value, Type targetType, object parameter, string la { bool invert = false; Boolean.TryParse((string)parameter, out invert); - + if (string.IsNullOrEmpty((string)value) ^ invert) { return Visibility.Collapsed; @@ -2065,4 +2086,20 @@ public object ConvertBack(object value, Type targetType, object parameter, strin } #endregion } + + public class IsIncenseActiveToPlayerIconConverter : IValueConverter + { + #region Implementation of IValueConverter + + public object Convert(object value, Type targetType, object parameter, string language) + { + return ((bool)value) ? new Uri($"ms-appx:///Assets/Ui/ash_withincense.png") : new Uri($"ms-appx:///Assets/Ui/ash.png"); + } + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + throw new NotImplementedException(); + } + + #endregion + } } diff --git a/PokemonGo-UWP/Utils/GameClient.cs b/PokemonGo-UWP/Utils/GameClient.cs index 008dd89cd..65a319f73 100644 --- a/PokemonGo-UWP/Utils/GameClient.cs +++ b/PokemonGo-UWP/Utils/GameClient.cs @@ -68,6 +68,11 @@ private class Heartbeat /// private DispatcherTimer _mapUpdateTimer; + /// + /// Timer used to update applied item + /// + private DispatcherTimer _appliedItemUpdateTimer; + /// /// True if another update operation is in progress. /// @@ -149,14 +154,37 @@ private async void HeartbeatTick(object sender, object o) internal async Task StartDispatcher() { _keepHeartbeating = true; - if (_mapUpdateTimer != null) return; + if (_mapUpdateTimer == null) + { + await DispatcherHelper.RunInDispatcherAndAwait(() => + { + _mapUpdateTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) }; + _mapUpdateTimer.Tick += HeartbeatTick; + _mapUpdateTimer.Start(); + }); + } + if (_appliedItemUpdateTimer == null) + { + await DispatcherHelper.RunInDispatcherAndAwait((Action)(() => + { + _appliedItemUpdateTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) }; + _appliedItemUpdateTimer.Tick += this._appliedItemUpdateTimer_Tick; + _appliedItemUpdateTimer.Start(); + })); + } + } - await DispatcherHelper.RunInDispatcherAndAwait(() => + private void _appliedItemUpdateTimer_Tick(object sender, object e) + { + foreach (AppliedItemWrapper appliedItem in AppliedItems) { - _mapUpdateTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) }; - _mapUpdateTimer.Tick += HeartbeatTick; - _mapUpdateTimer.Start(); - }); + if (appliedItem.IsExpired) + { + AppliedItems.Remove(appliedItem); + break; + } + appliedItem.Update(appliedItem.WrappedData); + } } /// @@ -203,8 +231,24 @@ public static string CurrentVersion /// public static InventoryDelta InventoryDelta { get; private set; } + public static bool IsIncenseActive + { + get { return AppliedItems.Count(x => x.ItemType == ItemType.Incense && !x.IsExpired) > 0; } + } + + public static bool IsXpBoostActive + { + get { return AppliedItems.Count(x => x.ItemType == ItemType.XpBoost && !x.IsExpired) > 0; } + } + #region Collections + /// + /// Collection of applied items + /// + public static ObservableCollection AppliedItems { get; set; } = + new ObservableCollection(); + /// /// Collection of Pokemon in 1 step from current position /// @@ -222,6 +266,11 @@ public static string CurrentVersion /// public static ObservableCollection LuredPokemons { get; set; } = new ObservableCollection(); + /// + /// Collection of incense Pokemon + /// + public static ObservableCollection IncensePokemons { get; set; } = new ObservableCollection(); + /// /// Collection of Pokestops in the current area /// @@ -308,6 +357,7 @@ public static string CurrentVersion static GameClient() { PokedexInventory.CollectionChanged += PokedexInventory_CollectionChanged; + AppliedItems.CollectionChanged += AppliedItems_CollectionChanged; // TODO: Investigate whether or not this needs to be unsubscribed when the app closes. } @@ -330,6 +380,18 @@ private static void PokedexInventory_CollectionChanged(object sender, NotifyColl } } + private static void AppliedItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.Action == NotifyCollectionChangedAction.Add) + { + OnAppliedItemStarted?.Invoke(null, (AppliedItemWrapper)e.NewItems[0]); + } + else if (e.Action == NotifyCollectionChangedAction.Remove) + { + OnAppliedItemExpired?.Invoke(null, (AppliedItemWrapper)e.OldItems[0]); + } + } + #endregion #region Game Logic @@ -491,8 +553,8 @@ public static void DoLogout() if (!SettingsService.Instance.RememberLoginData) SettingsService.Instance.UserCredentials = null; _heartbeat?.StopDispatcher(); - LocationServiceHelper.Instance.PropertyChanged -= LocationHelperPropertyChanged; - _lastGeopositionMapObjectsRequest = null; + LocationServiceHelper.Instance.PropertyChanged -= LocationHelperPropertyChanged; + _lastGeopositionMapObjectsRequest = null; } #endregion @@ -503,6 +565,8 @@ public static void DoLogout() private static Heartbeat _heartbeat; public static event EventHandler OnEggHatched; + public static event EventHandler OnAppliedItemExpired; + public static event EventHandler OnAppliedItemStarted; #region Compass Stuff /// @@ -545,12 +609,12 @@ public static async Task InitializeDataUpdate() }; //Trick to trigger the PropertyChanged for MapAutomaticOrientationMode ;) SettingsService.Instance.MapAutomaticOrientationMode = SettingsService.Instance.MapAutomaticOrientationMode; - #endregion - Busy.SetBusy(true, Resources.CodeResources.GetString("GettingGpsSignalText")); - await LocationServiceHelper.Instance.InitializeAsync(); - LocationServiceHelper.Instance.PropertyChanged += LocationHelperPropertyChanged; - // Before starting we need game settings - GameSetting = + #endregion + Busy.SetBusy(true, Resources.CodeResources.GetString("GettingGpsSignalText")); + await LocationServiceHelper.Instance.InitializeAsync(); + LocationServiceHelper.Instance.PropertyChanged += LocationHelperPropertyChanged; + // Before starting we need game settings + GameSetting = await DataCache.GetAsync(nameof(GameSetting), async () => (await _client.Download.GetSettings()).Settings, DateTime.Now.AddMonths(1)); @@ -564,7 +628,7 @@ public static async Task InitializeDataUpdate() //await UpdateMapObjects(); await UpdateInventory(); await UpdateItemTemplates(); - if(PlayerProfile != null && PlayerStats != null) + if (PlayerProfile != null && PlayerStats != null) Busy.SetBusy(false); } @@ -666,6 +730,20 @@ private static async Task UpdateMapObjects() var newLuredPokemon = newPokeStops.Where(item => item.LureInfo != null).Select(item => new LuredPokemon(item.LureInfo, item.Latitude, item.Longitude)).ToArray(); Logger.Write($"Found {newLuredPokemon.Length} lured Pokemon"); LuredPokemons.UpdateByIndexWith(newLuredPokemon, x => x); + + // Update IncensePokemon + if (IsIncenseActive) + { + var incensePokemonResponse = await GetIncensePokemons(LocationServiceHelper.Instance.Geoposition); + if (incensePokemonResponse.Result == GetIncensePokemonResponse.Types.Result.IncenseEncounterAvailable) + { + IncensePokemon[] newIncensePokemon; + newIncensePokemon = new IncensePokemon[1]; + newIncensePokemon[0] = new IncensePokemon(incensePokemonResponse, incensePokemonResponse.Latitude, incensePokemonResponse.Longitude); + Logger.Write($"Found incense Pokemon {incensePokemonResponse.PokemonId}"); + IncensePokemons.UpdateByIndexWith(newIncensePokemon, x => x); + } + } Logger.Write("Finished updating map objects"); // Update Hatched Eggs @@ -683,7 +761,7 @@ private static async Task UpdateMapObjects() var currentPokemon = PokemonsInventory .FirstOrDefault(item => item.Id == hatchedEggResponse.PokemonId[i]); - if(currentPokemon == null) + if (currentPokemon == null) continue; await @@ -694,7 +772,7 @@ private static async Task UpdateMapObjects() BootStrapper.Current.NavigationService.Navigate(typeof(PokemonDetailPage), new SelectedPokemonNavModel() { - SelectedPokemonId = currentPokemon.PokemonId.ToString(), + SelectedPokemonId = currentPokemon.Id.ToString(), ViewMode = PokemonDetailPageViewMode.ReceivedPokemon }); } @@ -723,6 +801,18 @@ private static async return await _client.Map.GetMapObjects(); } + /// + /// Gets updated incense Pokemon data based on provided position + /// + /// + /// + private static async + Task + GetIncensePokemons(Geoposition geoposition) + { + return await _client.Map.GetIncensePokemons(); + } + #endregion #region Player Data & Inventory @@ -881,6 +971,11 @@ public static async Task UpdateInventory() item.InventoryItemData.Item != null && CatchItemIds.Contains(item.InventoryItemData.Item.ItemId)) .GroupBy(item => item.InventoryItemData.Item) .Select(item => item.First().InventoryItemData.Item), true); + AppliedItems.AddRange( + fullInventory + .Where(item => item.InventoryItemData.AppliedItems != null) + .SelectMany(item => item.InventoryItemData.AppliedItems.Item) + .Select(item => new AppliedItemWrapper(item)), true); // Update incbuators IncubatorsInventory.AddRange(fullInventory.Where(item => item.InventoryItemData.EggIncubators != null) @@ -952,6 +1047,17 @@ public static async Task EncounterLurePokemon(ulong encou return await _client.Encounter.EncounterLurePokemon(encounterId, spawnpointId); } + /// + /// Encounters the selected incense pokemon + /// + /// + /// + /// + public static async Task EncounterIncensePokemon(ulong encounterId, string spawnpointId) + { + return await _client.Encounter.EncounterIncensePokemon(encounterId, spawnpointId); + } + /// /// Executes Pokemon catching /// @@ -1095,6 +1201,26 @@ public static async Task GetGymDetails(string gymid, doub #region Items Handling + /// + /// Uses the given incense item + /// + /// + /// + public static async Task UseIncense(ItemId item) + { + return await _client.Inventory.UseIncense(item); + } + + /// + /// Uses the given XpBoost item + /// + /// + /// + public static async Task UseXpBoost(ItemId item) + { + return await _client.Inventory.UseItemXpBoost(); + } + /// /// Recycles the given amount of the selected item /// diff --git a/PokemonGo-UWP/ViewModels/CapturePokemonPageViewModel.cs b/PokemonGo-UWP/ViewModels/CapturePokemonPageViewModel.cs index f8de86ef8..edca3ff77 100644 --- a/PokemonGo-UWP/ViewModels/CapturePokemonPageViewModel.cs +++ b/PokemonGo-UWP/ViewModels/CapturePokemonPageViewModel.cs @@ -54,7 +54,7 @@ private async Task HandleEncounter() ReturnToGameScreen.Execute(); break; case EncounterResponse.Types.Status.EncounterSuccess: - break; + break; case EncounterResponse.Types.Status.EncounterError: case EncounterResponse.Types.Status.EncounterNotFound: case EncounterResponse.Types.Status.EncounterClosed: @@ -69,13 +69,13 @@ private async Task HandleEncounter() case EncounterResponse.Types.Status.EncounterAlreadyHappened: await new MessageDialog(Resources.CodeResources.GetString("PokemonRanAwayText")).ShowAsyncQueue(); ReturnToGameScreen.Execute(); - GameClient.CatchablePokemons.Remove((MapPokemonWrapper) CurrentPokemon); + GameClient.CatchablePokemons.Remove((MapPokemonWrapper)CurrentPokemon); break; default: throw new ArgumentOutOfRangeException(); } } - else + else if (CurrentPokemon is LuredPokemon) { CurrentLureEncounter = await GameClient.EncounterLurePokemon(CurrentPokemon.EncounterId, CurrentPokemon.SpawnpointId); CurrentEncounter = new EncounterResponse() @@ -111,6 +111,34 @@ private async Task HandleEncounter() throw new ArgumentOutOfRangeException(); } } + else if (CurrentPokemon is IncensePokemon) + { + CurrentIncenseEncounter = await GameClient.EncounterIncensePokemon(CurrentPokemon.EncounterId, CurrentPokemon.SpawnpointId); + CurrentEncounter = new EncounterResponse() + { + Background = EncounterResponse.Types.Background.Park, + WildPokemon = new WildPokemon() + { + PokemonData = CurrentIncenseEncounter.PokemonData + } + }; + switch (CurrentIncenseEncounter.Result) + { + case IncenseEncounterResponse.Types.Result.PokemonInventoryFull: + await new MessageDialog(string.Format(Resources.CodeResources.GetString("PokemonInventoryFullText"), Resources.Pokemon.GetString($"{ CurrentPokemon.PokemonId}"))).ShowAsyncQueue(); + ReturnToGameScreen.Execute(); + break; + case IncenseEncounterResponse.Types.Result.IncenseEncounterSuccess: + break; + case IncenseEncounterResponse.Types.Result.IncenseEncounterUnknown: + case IncenseEncounterResponse.Types.Result.IncenseEncounterNotAvailable: + await new MessageDialog(string.Format(Resources.CodeResources.GetString("PokemonEncounterErrorText"), Resources.Pokemon.GetString($"{CurrentPokemon.PokemonId}"))).ShowAsyncQueue(); + ReturnToGameScreen.Execute(); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } PokemonExtraData = GameClient.GetExtraDataForPokemon(CurrentPokemon.PokemonId); SelectedCaptureItem = SelectAvailablePokeBall(); Busy.SetBusy(false); @@ -129,22 +157,25 @@ public override async Task OnNavigatedToAsync(object parameter, NavigationMode m // Recovering the state CurrentEncounter = new EncounterResponse(); CurrentLureEncounter = new DiskEncounterResponse(); + CurrentIncenseEncounter = new IncenseEncounterResponse(); CurrentCaptureAward = new CaptureAward(); SelectedCaptureItem = new ItemData(); - CurrentPokemon = JsonConvert.DeserializeObject((string) suspensionState[nameof(CurrentPokemon)]); + CurrentPokemon = JsonConvert.DeserializeObject((string)suspensionState[nameof(CurrentPokemon)]); CurrentEncounter.MergeFrom(ByteString.FromBase64((string)suspensionState[nameof(CurrentEncounter)]).CreateCodedInput()); CurrentLureEncounter.MergeFrom(ByteString.FromBase64((string)suspensionState[nameof(CurrentLureEncounter)]).CreateCodedInput()); + CurrentIncenseEncounter.MergeFrom(ByteString.FromBase64((string)suspensionState[nameof(CurrentIncenseEncounter)]).CreateCodedInput()); CurrentCaptureAward.MergeFrom(ByteString.FromBase64((string)suspensionState[nameof(CurrentCaptureAward)]).CreateCodedInput()); SelectedCaptureItem.MergeFrom(ByteString.FromBase64((string)suspensionState[nameof(SelectedCaptureItem)]).CreateCodedInput()); RaisePropertyChanged(() => CurrentEncounter); RaisePropertyChanged(() => CurrentLureEncounter); + RaisePropertyChanged(() => CurrentIncenseEncounter); RaisePropertyChanged(() => CurrentCaptureAward); RaisePropertyChanged(() => SelectedCaptureItem); } else { // Navigating from game page, so we need to actually load the encounter - CurrentPokemon = (IMapPokemon) NavigationHelper.NavigationState[nameof(CurrentPokemon)]; + CurrentPokemon = (IMapPokemon)NavigationHelper.NavigationState[nameof(CurrentPokemon)]; Busy.SetBusy(true, string.Format(Resources.CodeResources.GetString("LoadingEncounterText"), Resources.Pokemon.GetString(CurrentPokemon.PokemonId.ToString()))); NavigationHelper.NavigationState.Remove(nameof(CurrentPokemon)); Logger.Write($"Catching {CurrentPokemon.PokemonId}"); @@ -165,6 +196,7 @@ public override async Task OnNavigatedFromAsync(IDictionary susp suspensionState[nameof(CurrentPokemon)] = JsonConvert.SerializeObject(CurrentPokemon); suspensionState[nameof(CurrentEncounter)] = CurrentEncounter.ToByteString().ToBase64(); suspensionState[nameof(CurrentLureEncounter)] = CurrentLureEncounter.ToByteString().ToBase64(); + suspensionState[nameof(CurrentIncenseEncounter)] = CurrentIncenseEncounter.ToByteString().ToBase64(); suspensionState[nameof(CurrentCaptureAward)] = CurrentCaptureAward.ToByteString().ToBase64(); suspensionState[nameof(SelectedCaptureItem)] = SelectedCaptureItem.ToByteString().ToBase64(); } @@ -197,10 +229,15 @@ public override async Task OnNavigatingFromAsync(NavigatingEventArgs args) private EncounterResponse _currentEncounter; /// - /// Encounter for the Pokemon that we're trying to capture + /// Encounter for the lured Pokemon that we're trying to capture /// private DiskEncounterResponse _currentLureEncounter; + /// + /// Encounter for the incense Pokemon that we're trying to capture + /// + private IncenseEncounterResponse _currentIncenseEncounter; + /// /// Current item for capture page /// @@ -241,7 +278,7 @@ public EncounterResponse CurrentEncounter } /// - /// Encounter for the Pokemon that we're trying to capture + /// Encounter for the lured Pokemon that we're trying to capture /// public DiskEncounterResponse CurrentLureEncounter { @@ -249,6 +286,15 @@ public DiskEncounterResponse CurrentLureEncounter set { Set(ref _currentLureEncounter, value); } } + /// + /// Encounter for the lured Pokemon that we're trying to capture + /// + public IncenseEncounterResponse CurrentIncenseEncounter + { + get { return _currentIncenseEncounter; } + set { Set(ref _currentIncenseEncounter, value); } + } + /// /// Current item for capture page /// @@ -364,7 +410,7 @@ public PokemonSettings PokemonExtraData public ItemData SelectAvailablePokeBall() { var pokeball = SelectPokeballType(ItemId.ItemPokeBall); - if(pokeball != null && pokeball.Count != 0) + if (pokeball != null && pokeball.Count != 0) return pokeball; var greatball = SelectPokeballType(ItemId.ItemGreatBall); @@ -379,7 +425,7 @@ public ItemData SelectAvailablePokeBall() if (masterball != null && masterball.Count != 0) return masterball; - var fallback = new ItemData {Count = 0, ItemId = ItemId.ItemPokeBall}; + var fallback = new ItemData { Count = 0, ItemId = ItemId.ItemPokeBall }; return fallback; } @@ -456,7 +502,7 @@ private async Task ThrowPokeball(bool hitPokemon) var responseDelay = DateTime.Now - requestTime; if (responseDelay.TotalSeconds < 5 && hitPokemon) - await Task.Delay(TimeSpan.FromSeconds(5 - (int) responseDelay.TotalSeconds)); + await Task.Delay(TimeSpan.FromSeconds(5 - (int)responseDelay.TotalSeconds)); var nearbyPokemon = GameClient.NearbyPokemons.FirstOrDefault(pokemon => pokemon.EncounterId == CurrentPokemon.EncounterId); switch (caughtPokemonResponse.Status) @@ -472,9 +518,11 @@ private async Task ThrowPokeball(bool hitPokemon) CatchSuccess?.Invoke(this, null); _capturedPokemonId = caughtPokemonResponse.CapturedPokemonId; if (CurrentPokemon is MapPokemonWrapper) - GameClient.CatchablePokemons.Remove((MapPokemonWrapper) CurrentPokemon); - else - GameClient.LuredPokemons.Remove((LuredPokemon) CurrentPokemon); + GameClient.CatchablePokemons.Remove((MapPokemonWrapper)CurrentPokemon); + else if (CurrentPokemon is LuredPokemon) + GameClient.LuredPokemons.Remove((LuredPokemon)CurrentPokemon); + else if (CurrentPokemon is IncensePokemon) + GameClient.IncensePokemons.Remove((IncensePokemon)CurrentPokemon); GameClient.NearbyPokemons.Remove(nearbyPokemon); return true; @@ -488,9 +536,11 @@ private async Task ThrowPokeball(bool hitPokemon) Logger.Write($"{CurrentPokemon.PokemonId} fled"); CatchFlee?.Invoke(this, null); if (CurrentPokemon is MapPokemonWrapper) - GameClient.CatchablePokemons.Remove((MapPokemonWrapper) CurrentPokemon); - else - GameClient.LuredPokemons.Remove((LuredPokemon) CurrentPokemon); + GameClient.CatchablePokemons.Remove((MapPokemonWrapper)CurrentPokemon); + else if (CurrentPokemon is LuredPokemon) + GameClient.LuredPokemons.Remove((LuredPokemon)CurrentPokemon); + else if (CurrentPokemon is IncensePokemon) + GameClient.IncensePokemons.Remove((IncensePokemon)CurrentPokemon); GameClient.NearbyPokemons.Remove(nearbyPokemon); // We just go back because there's nothing else to do GameClient.ToggleUpdateTimer(); @@ -505,7 +555,7 @@ private async Task ThrowPokeball(bool hitPokemon) } return false; - } + } /// /// Uses the selected berry for the current encounter diff --git a/PokemonGo-UWP/ViewModels/GameMapPageViewModel.cs b/PokemonGo-UWP/ViewModels/GameMapPageViewModel.cs index e89cb93fd..e7ba4323f 100644 --- a/PokemonGo-UWP/ViewModels/GameMapPageViewModel.cs +++ b/PokemonGo-UWP/ViewModels/GameMapPageViewModel.cs @@ -23,6 +23,7 @@ using POGOProtos.Map.Pokemon; using Google.Protobuf; using PokemonGo_UWP.Controls; +using POGOProtos.Inventory; namespace PokemonGo_UWP.ViewModels { @@ -56,6 +57,17 @@ public GameMapPageViewModel() } } + private void GameClient_OnAppliedItemExpired(object sender, AppliedItemWrapper e) + { + RaisePropertyChanged("IsIncenseActive"); + AppliedItemExpired?.Invoke(null, e); + } + + private void GameClient_OnAppliedItemStarted(object sender, AppliedItemWrapper e) + { + RaisePropertyChanged("IsIncenseActive"); + AppliedItemStarted?.Invoke(null, e); + } #region Lifecycle Handlers @@ -68,6 +80,9 @@ public GameMapPageViewModel() public override async Task OnNavigatedToAsync(object parameter, NavigationMode mode, IDictionary suspensionState) { + GameClient.OnAppliedItemExpired += GameClient_OnAppliedItemExpired; + GameClient.OnAppliedItemStarted += GameClient_OnAppliedItemStarted; + // Prevent from going back to other pages NavigationService.ClearHistory(); if (parameter == null || mode == NavigationMode.Back) return; @@ -128,7 +143,7 @@ public override async Task OnNavigatedToAsync(object parameter, NavigationMode m public override async Task OnNavigatedFromAsync(IDictionary suspensionState, bool suspending) { if (suspending) - { + { suspensionState[nameof(PlayerProfile)] = PlayerProfile.ToByteString().ToBase64(); suspensionState[nameof(PlayerStats)] = PlayerStats.ToByteString().ToBase64(); } @@ -202,6 +217,13 @@ public LevelUpRewardsResponse LevelUpResponse private set { Set(ref _levelUpRewards, value); } } + /// + /// Collection of Applied items, like Incense + /// + public static ObservableCollection AppliedItems => GameClient.AppliedItems; + + public static bool IsIncenseActive => GameClient.IsIncenseActive; + /// /// Collection of Pokemon in 1 step from current position /// @@ -212,6 +234,11 @@ public LevelUpRewardsResponse LevelUpResponse /// public static ObservableCollection LuredPokemon => GameClient.LuredPokemons; + /// + /// Collection of incense Pokemon + /// + public static ObservableCollection IncensePokemon => GameClient.IncensePokemons; + /// /// Collection of Pokemon in 2 steps from current position /// @@ -242,6 +269,20 @@ public LevelUpRewardsResponse LevelUpResponse #endregion + #region AppliedItem Events + + /// + /// Event fired when an applied item has expired + /// + public event EventHandler AppliedItemExpired; + + /// + /// Event fired when an new item has been applied + /// + public event EventHandler AppliedItemStarted; + + #endregion + /// /// Waits for GPS auth and, if auth is given, starts updating data /// diff --git a/PokemonGo-UWP/ViewModels/ItemsInventoryPageViewModel.cs b/PokemonGo-UWP/ViewModels/ItemsInventoryPageViewModel.cs index d6e2cf447..2ae879202 100644 --- a/PokemonGo-UWP/ViewModels/ItemsInventoryPageViewModel.cs +++ b/PokemonGo-UWP/ViewModels/ItemsInventoryPageViewModel.cs @@ -12,6 +12,8 @@ using PokemonGo_UWP.Controls; using POGOProtos.Networking.Responses; using System; +using POGOProtos.Inventory; +using PokemonGo.RocketAPI.Extensions; namespace PokemonGo_UWP.ViewModels { @@ -136,6 +138,91 @@ public DelegateCommand ReturnToGameScreen #endregion + #region Use + + private DelegateCommand _useItemCommand; + + public DelegateCommand UseItemCommand => _useItemCommand ?? ( + _useItemCommand = new DelegateCommand((ItemDataWrapper item) => + { + if (item.ItemId == POGOProtos.Inventory.Item.ItemId.ItemIncenseOrdinary || + item.ItemId == POGOProtos.Inventory.Item.ItemId.ItemIncenseSpicy || + item.ItemId == POGOProtos.Inventory.Item.ItemId.ItemIncenseFloral || + item.ItemId == POGOProtos.Inventory.Item.ItemId.ItemIncenseCool) + { + if (!GameClient.IsIncenseActive) + { + var dialog = new PoGoMessageDialog("", string.Format(Resources.CodeResources.GetString("ItemUseQuestionText"), Resources.Items.GetString(item.ItemId.ToString()))); + dialog.AcceptText = Resources.CodeResources.GetString("YesText"); + dialog.CancelText = Resources.CodeResources.GetString("CancelText"); + dialog.CoverBackground = true; + dialog.AnimationType = PoGoMessageDialogAnimation.Bottom; + dialog.AcceptInvoked += async (sender, e) => + { + //// Send use request + var res = await GameClient.UseIncense(item.ItemId); + switch (res.Result) + { + case UseIncenseResponse.Types.Result.Success: + GameClient.AppliedItems.Add(new AppliedItemWrapper(res.AppliedIncense)); + ReturnToGameScreen.Execute(); + break; + case UseIncenseResponse.Types.Result.IncenseAlreadyActive: + ReturnToGameScreen.Execute(); + break; + case UseIncenseResponse.Types.Result.LocationUnset: + case UseIncenseResponse.Types.Result.NoneInInventory: + case UseIncenseResponse.Types.Result.Unknown: + break; + default: + throw new ArgumentOutOfRangeException(); + } + }; + + dialog.Show(); + } + } + + if (item.ItemId == POGOProtos.Inventory.Item.ItemId.ItemLuckyEgg) + { + if (!GameClient.IsXpBoostActive) + { + var dialog = new PoGoMessageDialog("", string.Format(Resources.CodeResources.GetString("ItemUseQuestionText"), Resources.Items.GetString(item.ItemId.ToString()))); + dialog.AcceptText = Resources.CodeResources.GetString("YesText"); + dialog.CancelText = Resources.CodeResources.GetString("CancelText"); + dialog.CoverBackground = true; + dialog.AnimationType = PoGoMessageDialogAnimation.Bottom; + dialog.AcceptInvoked += async (sender, e) => + { + // Send use request + var res = await GameClient.UseXpBoost(item.ItemId); + switch (res.Result) + { + case UseItemXpBoostResponse.Types.Result.Success: + AppliedItem appliedItem = res.AppliedItems.Item.FirstOrDefault(); + GameClient.AppliedItems.Add(new AppliedItemWrapper(appliedItem)); + ReturnToGameScreen.Execute(); + break; + case UseItemXpBoostResponse.Types.Result.ErrorXpBoostAlreadyActive: + ReturnToGameScreen.Execute(); + break; + case UseItemXpBoostResponse.Types.Result.ErrorInvalidItemType: + case UseItemXpBoostResponse.Types.Result.ErrorLocationUnset: + case UseItemXpBoostResponse.Types.Result.ErrorNoItemsRemaining: + case UseItemXpBoostResponse.Types.Result.Unset: + break; + default: + throw new ArgumentOutOfRangeException(); + } + }; + + dialog.Show(); + } + } + }, (ItemDataWrapper item) => true)); + + #endregion + #region Recycle private DelegateCommand _recycleItemCommand; diff --git a/PokemonGo-UWP/ViewModels/PokemonDetailPageViewModel.cs b/PokemonGo-UWP/ViewModels/PokemonDetailPageViewModel.cs index 4f5fcedf4..d36ad1bf1 100644 --- a/PokemonGo-UWP/ViewModels/PokemonDetailPageViewModel.cs +++ b/PokemonGo-UWP/ViewModels/PokemonDetailPageViewModel.cs @@ -330,14 +330,16 @@ public bool PlayerTeamIsSet { ServerRequestRunning = true; var isFavorite = Convert.ToBoolean(SelectedPokemon.Favorite); - var pokemonFavoriteResponse = await GameClient.SetFavoritePokemon(SelectedPokemon.Id, !isFavorite); + // Use local var to prevent bug when changing selected pokemon during running request + var favoritingPokemon = SelectedPokemon; + var pokemonFavoriteResponse = await GameClient.SetFavoritePokemon(favoritingPokemon.Id, !isFavorite); switch (pokemonFavoriteResponse.Result) { case SetFavoritePokemonResponse.Types.Result.Unset: break; case SetFavoritePokemonResponse.Types.Result.Success: // Inverse favorite state - SelectedPokemon.Favorite = Convert.ToInt32(!isFavorite); + favoritingPokemon.Favorite = Convert.ToInt32(!isFavorite); break; case SetFavoritePokemonResponse.Types.Result.ErrorPokemonNotFound: break; @@ -384,14 +386,17 @@ public bool PlayerTeamIsSet try { ServerRequestRunning = true; + // Use local var to prevent bug when changing selected pokemon during running request + var renamingPokemon = SelectedPokemon; + var nickname = textbox.Text; // Send rename request - var res = await GameClient.SetPokemonNickName((ulong)SelectedPokemon.Id, textbox.Text); + var res = await GameClient.SetPokemonNickName((ulong)renamingPokemon.Id, nickname); switch (res.Result) { case NicknamePokemonResponse.Types.Result.Unset: break; case NicknamePokemonResponse.Types.Result.Success: - SelectedPokemon.Nickname = textbox.Text; + renamingPokemon.Nickname = nickname; break; case NicknamePokemonResponse.Types.Result.ErrorPokemonNotFound: break; @@ -432,20 +437,27 @@ public bool PlayerTeamIsSet try { ServerRequestRunning = true; + // Use local var to prevent bug when changing selected pokemon during running request + var uppingPokemon = SelectedPokemon; // Send power up request - var res = await GameClient.PowerUpPokemon(SelectedPokemon.WrappedData); + var res = await GameClient.PowerUpPokemon(uppingPokemon.WrappedData); switch (res.Result) { case UpgradePokemonResponse.Types.Result.Unset: break; case UpgradePokemonResponse.Types.Result.Success: // Reload updated data - PokemonInventory.Remove(SelectedPokemon); + bool selectedPokemonSameAsUpping = uppingPokemon == SelectedPokemon; + PokemonInventory.Remove(uppingPokemon); var uppedPokemon = new PokemonDataWrapper(res.UpgradedPokemon); PokemonInventory.Add(uppedPokemon); PokemonInventory.SortBySortingmode(SortingMode); - SelectedPokemon = uppedPokemon; - RaisePropertyChanged(nameof(SelectedPokemon)); + // If the upping pokemon is still showing (not fliped to other), change selected to upped + if(selectedPokemonSameAsUpping) + { + SelectedPokemon = uppedPokemon; + RaisePropertyChanged(nameof(SelectedPokemon)); + } await GameClient.UpdateInventory(); await GameClient.UpdateProfile(); break; diff --git a/PokemonGo-UWP/ViewModels/PokemonInventoryPageViewModel.cs b/PokemonGo-UWP/ViewModels/PokemonInventoryPageViewModel.cs index cc289a1d1..ed623f584 100644 --- a/PokemonGo-UWP/ViewModels/PokemonInventoryPageViewModel.cs +++ b/PokemonGo-UWP/ViewModels/PokemonInventoryPageViewModel.cs @@ -185,15 +185,6 @@ public DelegateCommand ReturnToGameScreen #region Pokemon Inventory Handling - /// - /// Show sorting overlay for pokemon inventory - /// - private DelegateCommand _showPokemonSortingMenuCommand; - public DelegateCommand ShowPokemonSortingMenuCommand => _showPokemonSortingMenuCommand ?? (_showPokemonSortingMenuCommand = new DelegateCommand(() => - { - - })); - /// /// Sort the PokemonInventory with the CurrentPokemonSortingMode /// @@ -205,15 +196,6 @@ private void UpdateSorting() RaisePropertyChanged(() => PokemonInventory); } - /// - /// Show incubator overlay for egg inventory - /// - private DelegateCommand _showIncubatorOverlayCommand; - public DelegateCommand ShowIncubatorOverlayCommand => _showIncubatorOverlayCommand ?? (_showIncubatorOverlayCommand = new DelegateCommand(() => - { - - })); - #endregion #region Pokemon Detail diff --git a/PokemonGo-UWP/Views/AchievementDetailPage.xaml b/PokemonGo-UWP/Views/AchievementDetailPage.xaml index 79ad0546a..6b7c2989a 100644 --- a/PokemonGo-UWP/Views/AchievementDetailPage.xaml +++ b/PokemonGo-UWP/Views/AchievementDetailPage.xaml @@ -56,7 +56,7 @@ InnerSegmentColor="LightGray" RelativePanel.AlignHorizontalCenterWithPanel="True" RelativePanel.AlignVerticalCenterWithPanel="true" - ImageSourcePath="{Binding Achievement, Converter={StaticResource AchievementValueToMedalImageConverter}}" + ImageSourcePath="{Binding Achievement, Converter={StaticResource AchievementValueToMedalIconConverter}}" Maximum="{Binding Achievement, Converter={StaticResource AchievementNextValueConverter}}" Value="{Binding Achievement.Value, Converter={StaticResource AchievementValueConverter}}"/> diff --git a/PokemonGo-UWP/Views/GameMapPage.xaml b/PokemonGo-UWP/Views/GameMapPage.xaml index d827031d3..b908e1398 100644 --- a/PokemonGo-UWP/Views/GameMapPage.xaml +++ b/PokemonGo-UWP/Views/GameMapPage.xaml @@ -12,6 +12,7 @@ xmlns:viewModels="using:PokemonGo_UWP.ViewModels" xmlns:entities="using:PokemonGo_UWP.Entities" xmlns:controls="using:Template10.Controls" + xmlns:POGOcontrols="using:PokemonGo_UWP.Controls" xmlns:utils="using:PokemonGo_UWP.Utils" x:Name="GamePage" RequestedTheme="{Binding CurrentTheme, Mode=OneWay}" @@ -81,6 +82,13 @@ + + @@ -141,6 +149,13 @@ + + @@ -228,6 +243,14 @@ From="350" To="0" Duration="0:0:0.2" /> + + + @@ -237,6 +260,22 @@ From="0" To="350" Duration="0:0:0.2" /> + + + + + + + + + + + @@ -286,12 +325,12 @@ Canvas.ZIndex="1" x:Name="GameMapControl"> - + @@ -363,6 +402,23 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + public sealed partial class GameMapPage : Page - { + { private Geopoint lastAutoPosition; private Button ReactivateMapAutoUpdateButton; @@ -47,11 +48,11 @@ public GameMapPage() // Add reactivate map update button if (ReactivateMapAutoUpdateButton != null) return; - #region Reactivate Map AutoUpdate Button - ReactivateMapAutoUpdateButton = new Button + #region Reactivate Map AutoUpdate Button + ReactivateMapAutoUpdateButton = new Button { Visibility = Visibility.Collapsed, - Style = (Style) BootStrapper.Current.Resources["ImageButtonStyle"], + Style = (Style)BootStrapper.Current.Resources["ImageButtonStyle"], Height = 44, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, @@ -59,11 +60,11 @@ public GameMapPage() Content = new Image { Source = - new BitmapImage - { - UriSource = - new Uri($"ms-appx:///Assets/Icons/RecenterMapIcon{ViewModel.CurrentTheme}.png") - }, + new BitmapImage + { + UriSource = + new Uri($"ms-appx:///Assets/Icons/RecenterMapIcon{ViewModel.CurrentTheme}.png") + }, Stretch = Stretch.Uniform, Height = 36, HorizontalAlignment = HorizontalAlignment.Center, @@ -78,36 +79,36 @@ public GameMapPage() VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(GameMapControl, 0), 1), 0), 0); tsp.Children.Add(ReactivateMapAutoUpdateButton); - #endregion - #region Map Style button ;) - if (GameMapControl.Is3DSupported) - { - var MapStyleButton = new Button - { - Style = (Style)BootStrapper.Current.Resources["ImageButtonStyle"], - Height = 44, - HorizontalAlignment = HorizontalAlignment.Center, - VerticalAlignment = VerticalAlignment.Center, - Margin = new Thickness(0, 0, 0, 34), - Content = new Image - { - Source = - new BitmapImage - { - UriSource = - new Uri($"ms-appx:///Assets/Teams/no-team.png") - }, - Stretch = Stretch.Uniform, - Height = 36, - HorizontalAlignment = HorizontalAlignment.Stretch - } - }; - MapStyleButton.Tapped += MapStyleButton_Tapped; - - tsp.Children.Add(MapStyleButton); - } - #endregion - DisplayInformation.GetForCurrentView().OrientationChanged += GameMapPage_OrientationChanged; + #endregion + #region Map Style button ;) + if (GameMapControl.Is3DSupported) + { + var MapStyleButton = new Button + { + Style = (Style)BootStrapper.Current.Resources["ImageButtonStyle"], + Height = 44, + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + Margin = new Thickness(0, 0, 0, 34), + Content = new Image + { + Source = + new BitmapImage + { + UriSource = + new Uri($"ms-appx:///Assets/Teams/no-team.png") + }, + Stretch = Stretch.Uniform, + Height = 36, + HorizontalAlignment = HorizontalAlignment.Stretch + } + }; + MapStyleButton.Tapped += MapStyleButton_Tapped; + + tsp.Children.Add(MapStyleButton); + } + #endregion + DisplayInformation.GetForCurrentView().OrientationChanged += GameMapPage_OrientationChanged; }; } @@ -178,9 +179,9 @@ private async void ReactivateMapAutoUpdate_Tapped(object sender, TappedRoutedEve { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () => { - lastAutoPosition = null; - await UpdateMap(); - }); + lastAutoPosition = null; + await UpdateMap(); + }); } private void GameMapControl_TargetCameraChanged(MapControl sender, MapTargetCameraChangedEventArgs args) @@ -199,44 +200,44 @@ private void GameMapControl_OnZoomLevelChanged(MapControl sender, object args) protected override async void OnNavigatedTo(NavigationEventArgs e) { - try - { - base.OnNavigatedTo(e); - // Hide PokeMenu panel just in case - HidePokeMenuStoryboard.Begin(); - // See if we need to update the map - if ((e.Parameter != null) && (e.NavigationMode != NavigationMode.Back)) + try { - GameMapNavigationModes mode = - ((JObject) JsonConvert.DeserializeObject((string) e.Parameter)).Last - .ToObject(); - if ((mode == GameMapNavigationModes.AppStart) || (mode == GameMapNavigationModes.SettingsUpdate)) - SetupMap(); - } - // Set first position if we shomehow missed it + base.OnNavigatedTo(e); + // Hide PokeMenu panel just in case + HidePokeMenuStoryboard.Begin(); + // See if we need to update the map + if ((e.Parameter != null) && (e.NavigationMode != NavigationMode.Back)) + { + GameMapNavigationModes mode = + ((JObject)JsonConvert.DeserializeObject((string)e.Parameter)).Last + .ToObject(); + if ((mode == GameMapNavigationModes.AppStart) || (mode == GameMapNavigationModes.SettingsUpdate)) + SetupMap(); + } + // Set first position if we shomehow missed it await UpdateMap(); - //Changed order of calls, this allow to have events registration before trying to move map - //appears that for some reason TryRotate and/or TryTilt fails sometimes! - SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested; - SubscribeToCaptureEvents(); - - } - catch (Exception ex) - { - //because we are in "async void" unhandled exception might not be raised - await ExceptionHandler.HandleException(ex); - } - try - { - await GameMapControl.TryRotateToAsync(SettingsService.Instance.MapHeading); - await GameMapControl.TryTiltToAsync(SettingsService.Instance.MapPitch); - } - catch - { - //we don't care :) - } - - } + //Changed order of calls, this allow to have events registration before trying to move map + //appears that for some reason TryRotate and/or TryTilt fails sometimes! + SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested; + SubscribeToCaptureEvents(); + + } + catch (Exception ex) + { + //because we are in "async void" unhandled exception might not be raised + await ExceptionHandler.HandleException(ex); + } + try + { + await GameMapControl.TryRotateToAsync(SettingsService.Instance.MapHeading); + await GameMapControl.TryTiltToAsync(SettingsService.Instance.MapPitch); + } + catch + { + //we don't care :) + } + + } private void OnBackRequested(object sender, BackRequestedEventArgs backRequestedEventArgs) { @@ -252,11 +253,11 @@ protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) SystemNavigationManager.GetForCurrentView().BackRequested -= OnBackRequested; if (SettingsService.Instance.IsRememberMapZoomEnabled) SaveZoomLevel(); - SettingsService.Instance.MapPitch = GameMapControl.Pitch; - SettingsService.Instance.MapHeading = GameMapControl.Heading; - } + SettingsService.Instance.MapPitch = GameMapControl.Pitch; + SettingsService.Instance.MapHeading = GameMapControl.Heading; + } - private void SaveZoomLevel() + private void SaveZoomLevel() { // Bug fix for Issue 586 if ((SettingsService.Instance.Zoomlevel == 0) || (GameMapControl.ZoomLevel == 0)) @@ -277,24 +278,24 @@ private void SaveZoomLevel() private async Task UpdateMap() { - if (LocationServiceHelper.Instance.Geoposition != null) - { - await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () => + if (LocationServiceHelper.Instance.Geoposition != null) + { + await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () => { - try - { - // Set player icon's position - MapControl.SetLocation(PlayerImage, LocationServiceHelper.Instance.Geoposition.Coordinate.Point); + try + { + // Set player icon's position + MapControl.SetLocation(PlayerImage, LocationServiceHelper.Instance.Geoposition.Coordinate.Point); // Update angle and center only if map is not being manipulated if (lastAutoPosition == null) { - //Reset of position or first run - //Save Center + //Reset of position or first run + //Save Center lastAutoPosition = GameMapControl.Center; - //Reset orientation to default + //Reset orientation to default if (double.IsNaN(GameMapControl.Heading))//DarkAngel: I love non nullable double that can be "!= null and not a number"... - await GameMapControl.TryRotateToAsync(0); + await GameMapControl.TryRotateToAsync(0); } //Small Trick: I'm not testing lastAutoPosition == GameMapControl.Center because MapControl is not taking exact location when setting center!! @@ -305,34 +306,36 @@ await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () => if (currentCoord == previousCoord && ReactivateMapAutoUpdateButton != null) { //Previous position was set automatically, continue! - ReactivateMapAutoUpdateButton.Visibility = Visibility.Collapsed; - GameMapControl.Center = LocationServiceHelper.Instance.Geoposition.Coordinate.Point; + ReactivateMapAutoUpdateButton.Visibility = Visibility.Collapsed; + GameMapControl.Center = LocationServiceHelper.Instance.Geoposition.Coordinate.Point; lastAutoPosition = GameMapControl.Center; if ((SettingsService.Instance.MapAutomaticOrientationMode == MapAutomaticOrientationModes.GPS) && - ( - LocationServiceHelper.Instance.Geoposition.Coordinate.Heading.GetValueOrDefault(-1) >= 0 - && LocationServiceHelper.Instance.Geoposition.Coordinate.Heading.GetValueOrDefault(-1) <= 360 - )) - await GameMapControl.TryRotateToAsync(LocationServiceHelper.Instance.Geoposition.Coordinate.Heading.GetValueOrDefault(GameMapControl.Heading)); + ( + LocationServiceHelper.Instance.Geoposition.Coordinate.Heading.GetValueOrDefault(-1) >= 0 + && LocationServiceHelper.Instance.Geoposition.Coordinate.Heading.GetValueOrDefault(-1) <= 360 + )) + await GameMapControl.TryRotateToAsync(LocationServiceHelper.Instance.Geoposition.Coordinate.Heading.GetValueOrDefault(GameMapControl.Heading)); if (SettingsService.Instance.IsRememberMapZoomEnabled) GameMapControl.ZoomLevel = SettingsService.Instance.Zoomlevel; } - } - catch (Exception ex) - { - await ExceptionHandler.HandleException(ex); - } - }); - } - } + } + catch (Exception ex) + { + await ExceptionHandler.HandleException(ex); + } + }); + } + } private void SubscribeToCaptureEvents() { - LocationServiceHelper.Instance.PropertyChanged += LocationHelperPropertyChanged; + LocationServiceHelper.Instance.PropertyChanged += LocationHelperPropertyChanged; GameClient.HeadingUpdated += HeadingUpdated; ViewModel.LevelUpRewardsAwarded += ViewModelOnLevelUpRewardsAwarded; + ViewModel.AppliedItemExpired += ViewModelOnAppliedItemExpired; + ViewModel.AppliedItemStarted += ViewModelOnAppliedItemStarted; } private TimeSpan tick = new TimeSpan(DateTime.Now.Ticks); @@ -351,18 +354,18 @@ private async void HeadingUpdated(object sender, CompassReading e) private void UnsubscribeToCaptureEvents() { - LocationServiceHelper.Instance.PropertyChanged -= LocationHelperPropertyChanged; + LocationServiceHelper.Instance.PropertyChanged -= LocationHelperPropertyChanged; GameClient.HeadingUpdated -= HeadingUpdated; ViewModel.LevelUpRewardsAwarded -= ViewModelOnLevelUpRewardsAwarded; } - private async void LocationHelperPropertyChanged(object sender, PropertyChangedEventArgs e) - { - if (e.PropertyName == nameof(LocationServiceHelper.Instance.Geoposition)) - { - await UpdateMap(); - } - } + private async void LocationHelperPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == nameof(LocationServiceHelper.Instance.Geoposition)) + { + await UpdateMap(); + } + } private void ViewModelOnLevelUpRewardsAwarded(object sender, EventArgs eventArgs) { @@ -371,35 +374,45 @@ private void ViewModelOnLevelUpRewardsAwarded(object sender, EventArgs eventArgs ShowLevelUpPanelStoryboard.Begin(); } - #endregion - private async void MapStyleButton_Tapped(object sender, TappedRoutedEventArgs e) - { - if (GameMapControl.Is3DSupported) - { - switch (GameMapControl.Style) - { - case MapStyle.None: - GameMapControl.Style = MapStyle.Road; - break; - case MapStyle.Road: - GameMapControl.Style = MapStyle.Aerial3DWithRoads; - break; - case MapStyle.Aerial: - case MapStyle.AerialWithRoads: - case MapStyle.Terrain: - case MapStyle.Aerial3D: - case MapStyle.Aerial3DWithRoads: - GameMapControl.Style = MapStyle.Road; - break; - default: - GameMapControl.Style = MapStyle.Road; - break; - } - } - else - { - await new Windows.UI.Popups.MessageDialog("Sorry 3DView is not supported!").ShowAsyncQueue(); - } - } - } + #endregion + private async void MapStyleButton_Tapped(object sender, TappedRoutedEventArgs e) + { + if (GameMapControl.Is3DSupported) + { + switch (GameMapControl.Style) + { + case MapStyle.None: + GameMapControl.Style = MapStyle.Road; + break; + case MapStyle.Road: + GameMapControl.Style = MapStyle.Aerial3DWithRoads; + break; + case MapStyle.Aerial: + case MapStyle.AerialWithRoads: + case MapStyle.Terrain: + case MapStyle.Aerial3D: + case MapStyle.Aerial3DWithRoads: + GameMapControl.Style = MapStyle.Road; + break; + default: + GameMapControl.Style = MapStyle.Road; + break; + } + } + else + { + await new Windows.UI.Popups.MessageDialog("Sorry 3DView is not supported!").ShowAsyncQueue(); + } + } + + private void ViewModelOnAppliedItemExpired(object sender, AppliedItemWrapper AppliedItem) + { + HideAppliedItemStoryboard.Begin(); + } + + private void ViewModelOnAppliedItemStarted(object sender, AppliedItemWrapper AppliedItem) + { + ShowAppliedItemStoryboard.Begin(); + } + } } \ No newline at end of file diff --git a/PokemonGo-UWP/Views/Item/ItemsInventoryPage.xaml b/PokemonGo-UWP/Views/Item/ItemsInventoryPage.xaml index b16d08533..1e1d61af8 100644 --- a/PokemonGo-UWP/Views/Item/ItemsInventoryPage.xaml +++ b/PokemonGo-UWP/Views/Item/ItemsInventoryPage.xaml @@ -50,6 +50,12 @@ Margin="0" Grid.Row="1" Padding="0,0,0,60"> + + + + + +