// Invoked when application is being started up (before MainWindow creation). protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); AppDomain.CurrentDomain.UnhandledException += (_, args) => OnUnhandledException((Exception)args.ExceptionObject); // Create Mutex if this is first instance. try { _runningInstanceMutex = Mutex.OpenExisting(RunningInstanceMutexName); } catch (WaitHandleCannotBeOpenedException) { _runningInstanceMutex = new Mutex(false, RunningInstanceMutexName, out var created); if (!created) { throw new Exception("Unable to create application mutex"); } } // Load persistent data. // Take the first not-switch argument as path to the build that will be imported var importedBuildPath = e.Args.FirstOrDefault(s => !s.StartsWith("/")); PersistentData = PersistentDataSerializationService.CreatePersistentData(importedBuildPath); // Initialize localization. L10n.Initialize(PersistentData.Options.Language); }
public DownloadStashViewModel(IDialogCoordinator dialogCoordinator, IPersistentData persistentData, Stash stash) { _stash = stash; _persistenData = persistentData; _dialogCoordinator = dialogCoordinator; DisplayName = L10n.Message("Download & Import Stash"); Build = persistentData.CurrentBuild; if (Build.League != null && _persistenData.LeagueStashes.ContainsKey(Build.League)) _tabs = new List<StashBookmark>(_persistenData.LeagueStashes[Build.League]); TabsView = new ListCollectionView(_tabs); TabsView.CurrentChanged += (sender, args) => UpdateTabLink(); Build.PropertyChanged += BuildOnPropertyChanged; BuildOnPropertyChanged(this, null); RequestsClose += _ => Build.PropertyChanged -= BuildOnPropertyChanged; _viewLoadedCompletionSource = new TaskCompletionSource<object>(); if (CurrentLeagues == null) { CurrentLeagues = new NotifyingTask<IReadOnlyList<string>>(LoadCurrentLeaguesAsync(), async e => { await _viewLoadedCompletionSource.Task; await _dialogCoordinator.ShowWarningAsync(this, L10n.Message("Could not load the currently running leagues."), e.Message); }); } }
public DownloadStashViewModel(IDialogCoordinator dialogCoordinator, IPersistentData persistentData, StashViewModel stash) { _stash = stash; _persistenData = persistentData; _dialogCoordinator = dialogCoordinator; DisplayName = L10n.Message("Download & Import Stash"); Build = persistentData.CurrentBuild; if (Build.League != null && _persistenData.LeagueStashes.ContainsKey(Build.League)) { _tabs = new List <StashBookmark>(_persistenData.LeagueStashes[Build.League]); } TabsView = new ListCollectionView(_tabs); TabsView.CurrentChanged += (sender, args) => UpdateTabLink(); Build.PropertyChanged += BuildOnPropertyChanged; BuildOnPropertyChanged(this, null); _viewLoadedCompletionSource = new TaskCompletionSource <object>(); if (CurrentLeagues == null) { CurrentLeagues = new NotifyingTask <IReadOnlyList <string> >(LoadCurrentLeaguesAsync(), async e => { await _viewLoadedCompletionSource.Task; await _dialogCoordinator.ShowWarningAsync(this, L10n.Message("Could not load the currently running leagues."), e.Message); }); } }
public static void Connect( IPersistentData persistentData, ObservableCollection <ConfigurationStatViewModel> viewModels, IEnumerable <ConfigurationNodeViewModel> additionalNodes) { var nodes = viewModels.Select(x => x.Node).Concat(additionalNodes); var connector = new ConfigurationStatsConnector(persistentData, nodes); connector.Initialize(viewModels); }
public ImportViewModels( IDialogCoordinator dialogCoordinator, IPersistentData persistentData, StashViewModel stash) { _dialogCoordinator = dialogCoordinator; _persistentData = persistentData; _stash = stash; _httpClient = new HttpClient(); _currentLeagues = new Lazy <CurrentLeaguesViewModel>(() => new CurrentLeaguesViewModel(_httpClient)); _accountCharacters = new Lazy <AccountCharactersViewModel>(() => new AccountCharactersViewModel(_httpClient)); }
public static IDisposable UpdateScope <T>([NotNull] this IPersistentData <T> persistentData) where T : class, new() { if (persistentData == null) { throw new ArgumentNullException(nameof(persistentData)); } return(new ActionDisposable(persistentData.BeginUpdates, persistentData.EndUpdates)); }
public ItemAttributes(IPersistentData persistentData, string itemData) { _persistentData = persistentData; Equip = new ObservableCollection <Item>(); var jObject = JObject.Parse(itemData); foreach (JObject jobj in (JArray)jObject["items"]) { switch (jobj["inventoryId"].Value <string>()) { case "BodyArmour": AddItem(jobj, ItemSlot.Armor); break; case "Ring": AddItem(jobj, ItemSlot.Ring); break; case "Ring2": AddItem(jobj, ItemSlot.Ring2); break; case "Gloves": AddItem(jobj, ItemSlot.Gloves); break; case "Weapon": AddItem(jobj, ItemSlot.MainHand); break; case "Offhand": AddItem(jobj, ItemSlot.OffHand); break; case "Helm": AddItem(jobj, ItemSlot.Helm); break; case "Boots": AddItem(jobj, ItemSlot.Boots); break; case "Amulet": AddItem(jobj, ItemSlot.Amulet); break; case "Belt": AddItem(jobj, ItemSlot.Belt); break; } } RefreshItemAttributes(); }
public TreeGeneratorInteraction(ISettingsDialogCoordinator dialogCoordinator, IPersistentData persistentData, SkillTree skillTree) { _persistentData = persistentData; _dialogCoordinator = dialogCoordinator; SkillTree = skillTree; OpenTreeGeneratorCommand = new AsyncRelayCommand(OpenTreeGenerator); RunTaggedNodesCommand = new AsyncRelayCommand(RunTaggedNodes); RunAdvancedCommand = new AsyncRelayCommand(RunAdvanced); }
public TreeGeneratorInteraction(ISettingsDialogCoordinator dialogCoordinator, IPersistentData persistentData, SkillTree skillTree) { _persistentData = persistentData; _dialogCoordinator = dialogCoordinator; SkillTree = skillTree; OpenTreeGeneratorCommand = new AsyncRelayCommand(OpenTreeGenerator); RunTaggedNodesCommand = new AsyncRelayCommand(RunTaggedNodes); RunAdvancedCommand = new AsyncRelayCommand(RunAdvanced); }
public UserObject(IPersistentData persistentData, string id, string name, byte[] data = default, int offset = 0, int length = -1) { _persistentData = persistentData; Id = id; Name = name; _data = data; _offset = offset; if ((length == -1) && (_data != null)) { _length = _data.Length; } }
/// <summary> /// Initializes a new instance of the <see cref="TrackedStatsMenuModel"/> class. /// </summary> /// <param name="persistentData">The persistent data.</param> /// <param name="dialogCoordinator">The dialog coordinator.</param> public TrackedStatsMenuModel(IPersistentData persistentData, IDialogCoordinator dialogCoordinator) { _persistentData = persistentData; _dialogCoordinator = dialogCoordinator; Options = persistentData.Options; StatTrackingSavePath = persistentData.StatTrackingSavePath; DisplayName = L10n.Message("Tracked Stat Settings"); ChangeStatTrackingPathCommand = new AsyncRelayCommand(ChangeStatTrackingPath); Options.PropertyChanged += OptionsOnPropertyChanged; }
public SettingsMenuViewModel(IPersistentData persistentData, IDialogCoordinator dialogCoordinator, BuildsControlViewModel buildsControlViewModel) { _persistentData = persistentData; _dialogCoordinator = dialogCoordinator; _buildsControlViewModel = buildsControlViewModel; Options = persistentData.Options; DisplayName = L10n.Message("Options"); ChangeBuildsSavePathCommand = new AsyncRelayCommand(ChangeBuildsSavePath); Options.PropertyChanged += OptionsOnPropertyChanged; }
public SettingsMenuViewModel(IPersistentData persistentData, IDialogCoordinator dialogCoordinator) { _dialogCoordinator = dialogCoordinator; Options = persistentData.Options; DisplayName = L10n.Message("Settings"); PropertyChangedEventHandler handler = async(sender, args) => await OptionsChanged(args.PropertyName); Options.PropertyChanged += handler; RequestsClose += () => { Options.PropertyChanged -= handler; persistentData.SaveToFile(); }; }
public SettingsMenuViewModel(IPersistentData persistentData, IDialogCoordinator dialogCoordinator, BuildsControlViewModel buildsControlViewModel) { _persistentData = persistentData; _dialogCoordinator = dialogCoordinator; _buildsControlViewModel = buildsControlViewModel; Options = persistentData.Options; DisplayName = L10n.Message("Settings"); ChangeBuildsSavePathCommand = new AsyncRelayCommand(ChangeBuildsSavePath); PropertyChangedEventHandler handler = async (sender, args) => await OptionsChanged(args.PropertyName); Options.PropertyChanged += handler; RequestsClose += _ => { Options.PropertyChanged -= handler; persistentData.Save(); }; }
/// <summary> /// Constructs a new SettingsViewModel that operates on the given skill tree. /// </summary> /// <param name="tree">The skill tree to operate on. (not null)</param> /// <param name="persistentData"></param> /// <param name="dialogCoordinator"></param> /// <param name="dialogContext">The context used for <paramref name="dialogCoordinator"/>.</param> public SettingsViewModel(SkillTree tree, IPersistentData persistentData, ISettingsDialogCoordinator dialogCoordinator, object dialogContext) { Tree = tree; _dialogCoordinator = dialogCoordinator; _dialogContext = dialogContext; SelectedTabIndex = new LeafSetting <int>(nameof(SelectedTabIndex), 0); async void RunCallback(GeneratorTabViewModel g) => await RunAsync(g); Tabs = new ObservableCollection <GeneratorTabViewModel> { new SteinerTabViewModel(Tree, _dialogCoordinator, _dialogContext, RunCallback), new AdvancedTabViewModel(Tree, persistentData, _dialogCoordinator, _dialogContext, RunCallback), new AutomatedTabViewModel(Tree, _dialogCoordinator, _dialogContext, RunCallback) }; SubSettings = new ISetting[] { SelectedTabIndex }.Union(Tabs).ToArray(); }
public SettingsMenuViewModel(IPersistentData persistentData, IDialogCoordinator dialogCoordinator, BuildsControlViewModel buildsControlViewModel) { _persistentData = persistentData; _dialogCoordinator = dialogCoordinator; _buildsControlViewModel = buildsControlViewModel; Options = persistentData.Options; DisplayName = L10n.Message("Settings"); ChangeBuildsSavePathCommand = new AsyncRelayCommand(ChangeBuildsSavePath); PropertyChangedEventHandler handler = async(sender, args) => await OptionsChanged(args.PropertyName); Options.PropertyChanged += handler; RequestsClose += _ => { Options.PropertyChanged -= handler; persistentData.Save(); }; }
public void Initialize(IExtendedDialogCoordinator dialogCoordinator, IPersistentData persistentData) { _dialogCoordinator = dialogCoordinator; _persistentData = persistentData; // add view models for bookmarks and items // PersistentData.StashBookmarks and PersistentData.StashItems may only be changed through the stash after this BeginUpdate(); Bookmarks.AddRange(persistentData.StashBookmarks.Select(b => new StashBookmarkViewModel(b))); Bookmarks.CollectionChanged += (sender, args) => RowsChanged(); foreach (var stashItem in persistentData.StashItems) { var item = new StashItemViewModel(stashItem); item.PropertyChanging += ItemOnPropertyChanging; item.PropertyChanged += ItemOnPropertyChanged; Items.Add(item); } Items.CollectionChanged += ItemsOnCollectionChanged; EndUpdate(); }
public UserObjectsCollection([NotNull] IPersistentData persistentData, char idSeparator = '\n') { if (persistentData == null) { throw new ArgumentNullException(nameof(persistentData)); } _persistentData = persistentData; _idSeparator = idSeparator; var ids = _persistentData.GetString(CollectionKey); if (!string.IsNullOrEmpty(ids)) { _collection.AddRange(ids .Split(_idSeparator) .Select(id => new UserObject( persistentData, id, _persistentData.GetString(string.Format(NameKey, id))))); } }
public BuildsControlViewModel(IExtendedDialogCoordinator dialogCoordinator, IPersistentData persistentData, ISkillTree skillTree) { _dialogCoordinator = dialogCoordinator; PersistentData = persistentData; DropHandler = new CustomDropHandler(this); _buildValidator = new BuildValidator(PersistentData.Options); BuildRoot = new BuildFolderViewModel(persistentData.RootBuild, Filter, BuildOnCollectionChanged); _fileSystemWatcher = new FileSystemWatcher { Path = PersistentData.Options.BuildsSavePath, IncludeSubdirectories = true, NotifyFilter = NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastWrite }; _fileSystemWatcher.Error += FileSystemWatcherOnError; _fileSystemWatcher.Changed += FileSystemWatcherOnChanged; _fileSystemWatcher.Created += FileSystemWatcherOnChanged; _fileSystemWatcher.Deleted += FileSystemWatcherOnChanged; _fileSystemWatcher.Renamed += FileSystemWatcherOnChanged; _fileSystemWatcher.EnableRaisingEvents = true; // The monitor alone is not enough because delays are necessary and those shouldn't block other save // operations, which would happen if delays are awaited directly in the save method. // It could be done awaited with .ConfigureAwait(false) if SimpleMonitor would be thread safe. _changingFileSystemMonitor.Entered += (sender, args) => _changingFileSystemCounter++; _changingFileSystemMonitor.Freed += async(sender, args) => { // Wait because FileSystemWatcherOnChanged calls are delayed a bit. await Task.Delay(2000); // This is a counter and not boolean because other save operations may happen while waiting on delay. _changingFileSystemCounter--; }; CurrentBuild = TreeFindBuildViewModel(PersistentData.CurrentBuild); SelectedBuild = TreeFindBuildViewModel(PersistentData.SelectedBuild); PersistentData.PropertyChanged += PersistentDataOnPropertyChanged; PersistentData.Options.PropertyChanged += OptionsOnPropertyChanged; NewFolderCommand = new AsyncRelayCommand <IBuildFolderViewModel>( NewFolder, vm => vm != null && _buildValidator.CanHaveSubfolder(vm)); NewBuildCommand = new AsyncRelayCommand <IBuildFolderViewModel>(NewBuild); DeleteCommand = new AsyncRelayCommand <IBuildViewModel>( Delete, o => o != BuildRoot); OpenBuildCommand = new RelayCommand <BuildViewModel>(build => CurrentBuild = build); SaveBuildCommand = new AsyncRelayCommand <BuildViewModel>( SaveBuild, b => b != null && b.Build.IsDirty); SaveBuildAsCommand = new AsyncRelayCommand <BuildViewModel>(SaveBuildAs); SaveAllBuildsCommand = new AsyncRelayCommand( SaveAllBuilds, () => TreeFind <BuildViewModel>(b => b.Build.IsDirty, BuildRoot) != null); RevertBuildCommand = new RelayCommand <BuildViewModel>( build => build.Build.RevertChanges(), b => b != null && b.Build.IsDirty && b.Build.CanRevert); MoveUpCommand = new RelayCommand <IBuildViewModel>( MoveUp, o => o != BuildRoot && o.Parent.Children.IndexOf(o) > 0); MoveDownCommand = new RelayCommand <IBuildViewModel>( MoveDown, o => o != BuildRoot && o.Parent.Children.IndexOf(o) < o.Parent.Children.Count - 1); EditCommand = new AsyncRelayCommand <IBuildViewModel>(Edit); CutCommand = new AsyncRelayCommand <IBuildViewModel>( Cut, b => b != BuildRoot && b != CurrentBuild); CopyCommand = new RelayCommand <IBuildViewModel <PoEBuild> >(Copy); PasteCommand = new AsyncRelayCommand <IBuildViewModel>(Paste, CanPaste); ReloadCommand = new AsyncRelayCommand(Reload); OpenBuildsSavePathCommand = new RelayCommand(() => Process.Start(PersistentData.Options.BuildsSavePath)); ExpandAllCommand = new RelayCommand(ExpandAll); CollapseAllCommand = new RelayCommand(CollapseAll); SkillTree = skillTree; ClassFilterItems = GenerateAscendancyClassItems().ToList(); ClassFilter = NoFilterItem; }
public ExtendedDialogCoordinator(GameData gameData, IPersistentData persistentData) => (_gameData, _persistentData) = (gameData, persistentData);
public UserObject(IPersistentData persistentData, IUserObject other) : this(persistentData, other.Id, other.Name) { other.GetData(out _data, out _offset, out _length); }
public void RegisterDataHandler(IPersistentData handler) { }
public Item(IPersistentData persistentData, JObject val, ItemSlot itemSlot = ItemSlot.Unequipable, bool isGem = false) { JsonBase = val; Slot = itemSlot; Width = val["w"].Value <int>(); Height = val["h"].Value <int>(); if (val["x"] != null) { X = val["x"].Value <int>(); } if (val["y"] != null) { Y = val["y"].Value <int>(); } if (val["name"] != null) { NameLine = FilterJsonString(val["name"].Value <string>()); } JToken iconToken; if (val.TryGetValue("icon", out iconToken)) { _iconUrl = iconToken.Value <string>(); } Frame = (FrameType)val["frameType"].Value <int>(); TypeLine = FilterJsonString(val["typeLine"].Value <string>()); if (isGem) { // BaseType will be null for socketed gems. ItemClass = ItemClassEx.ItemClassForGem(TypeLine); Tags = ItemClass.ToTags(); } else { if (Frame == FrameType.Magic) { BaseType = persistentData.EquipmentData.ItemBaseFromTypeline(TypeLine); } else if ((Frame == FrameType.Unique || Frame == FrameType.Foil) && persistentData.EquipmentData.UniqueBaseDictionary.ContainsKey(NameLine)) { BaseType = persistentData.EquipmentData.UniqueBaseDictionary[NameLine]; } else { // item is not unique or the unique is unknown ItemBase iBase; persistentData.EquipmentData.ItemBaseDictionary.TryGetValue(TypeLine, out iBase); BaseType = iBase; } // For known bases, images are only downloaded if the item is unique or foil. All other items should // always have the same image. (except alt art non-uniques that are rare enough to be ignored) var loadImageFromIconUrl = _iconUrl != null && (BaseType == null || Frame == FrameType.Unique || Frame == FrameType.Foil); if (BaseType == null) { BaseType = new ItemBase(persistentData.EquipmentData.ItemImageService, itemSlot, TypeLine, Keywords == null ? "" : Keywords.FirstOrDefault(), Frame); } ItemClass = BaseType.ItemClass; Tags = BaseType.Tags; if (loadImageFromIconUrl) { Image = BaseType.Image.AsDefaultForImageFromUrl( persistentData.EquipmentData.ItemImageService, _iconUrl); } else { Image = BaseType.Image; } } if (val["properties"] != null) { foreach (var obj in val["properties"]) { Properties.Add(ItemModFromJson(obj, ModLocation.Property)); } if (Properties.Any(m => !m.Values.Any())) { // The name of one property of gems contains the Keywords of that gem. Keywords = Properties.First(m => !m.Values.Any()).Attribute.Split(',').Select(i => i.Trim()).ToList(); } } if (val["requirements"] != null) { var mods = val["requirements"].Select(t => ItemModFromJson(t, ModLocation.Requirement)).ToList(); if (!mods.Any(m => m.Attribute.StartsWith("Requires "))) { var modsToMerge = new [] { mods.FirstOrDefault(m => m.Attribute == "Level #"), mods.FirstOrDefault(m => m.Attribute == "# Str"), mods.FirstOrDefault(m => m.Attribute == "# Dex"), mods.FirstOrDefault(m => m.Attribute == "# Int") }.Where(m => m != null).ToList(); modsToMerge.ForEach(m => mods.Remove(m)); mods.Add(new ItemMod( "Requires " + string.Join(", ", modsToMerge.Select(m => m.Attribute)), false, modsToMerge.Select(m => m.Values).Flatten(), modsToMerge.Select(m => m.ValueColors).Flatten() )); } _requirements.AddRange(mods); } if (val["implicitMods"] != null) { foreach (var s in val["implicitMods"].Values <string>()) { _implicitMods.Add(ItemModFromString(FixOldRanges(s), ModLocation.Implicit)); } } if (val["explicitMods"] != null) { foreach (var s in val["explicitMods"].Values <string>()) { ExplicitMods.Add(ItemModFromString(FixOldRanges(s), ModLocation.Explicit)); } } if (val["craftedMods"] != null) { foreach (var s in val["craftedMods"].Values <string>()) { CraftedMods.Add(ItemModFromString(FixOldRanges(s), ModLocation.Crafted)); } } if (val["flavourText"] != null && val["flavourText"].HasValues) { FlavourText = string.Join("\r\n", val["flavourText"].Values <string>().Select(s => s.Replace("\r", ""))); } var sockets = new List <int>(); if (val["sockets"] != null) { foreach (var obj in (JArray)val["sockets"]) { sockets.Add(obj["group"].Value <int>()); } } if (val["socketedItems"] != null) { int socket = 0; foreach (JObject obj in (JArray)val["socketedItems"]) { var item = new Item(persistentData, obj, isGem: true) { SocketGroup = sockets[socket++] }; _gems.Add(item); } } }
/// <param name="persistentData">Instance to operate on</param> public PersistentDataSerializer(IPersistentData persistentData) { _persistentData = persistentData; InitParents(); InitNames(); }
/// <param name="persistentData">Instance to operate on</param> public PersistentDataSerializer(IPersistentData persistentData) { _persistentData = persistentData; InitParents(); InitNames(); }
public ItemAttributes(IPersistentData persistentData, string itemData) { _persistentData = persistentData; Equip = new ObservableCollection<Item>(); var jObject = JObject.Parse(itemData); foreach (JObject jobj in (JArray)jObject["items"]) { switch (jobj["inventoryId"].Value<string>()) { case "BodyArmour": AddItem(jobj, ItemSlot.Armor); break; case "Ring": AddItem(jobj, ItemSlot.Ring); break; case "Ring2": AddItem(jobj, ItemSlot.Ring2); break; case "Gloves": AddItem(jobj, ItemSlot.Gloves); break; case "Weapon": AddItem(jobj, ItemSlot.MainHand); break; case "Offhand": AddItem(jobj, ItemSlot.OffHand); break; case "Helm": AddItem(jobj, ItemSlot.Helm); break; case "Boots": AddItem(jobj, ItemSlot.Boots); break; case "Amulet": AddItem(jobj, ItemSlot.Amulet); break; case "Belt": AddItem(jobj, ItemSlot.Belt); break; } } RefreshItemAttributes(); }
public ConfigurationStatsConnector( IPersistentData persistentData, IEnumerable <ConfigurationNodeViewModel> nodes) { _persistentData = persistentData; _nodes = nodes; }
public ArticleModelWithCategory(IUnitOfWork unitOfWork, IPersistentData data) { _unitOfWork = unitOfWork; _data = data; }
private SkillTree(IPersistentData persistentData, IDialogCoordinator dialogCoordinator) { _persistentData = persistentData; _dialogCoordinator = dialogCoordinator; }
/// <summary> /// Returns a task that finishes with a SkillTree object once it has been initialized. /// </summary> /// <param name="persistentData"></param> /// <param name="dialogCoordinator">Can be null if the resulting tree is not used.</param> /// <param name="controller">Null if no initialization progress should be displayed.</param> /// <param name="assetLoader">Can optionally be provided if the caller wants to backup assets.</param> /// <returns></returns> public static async Task<SkillTree> CreateAsync(IPersistentData persistentData, IDialogCoordinator dialogCoordinator, ProgressDialogController controller = null, AssetLoader assetLoader = null) { controller?.SetProgress(0); var dataFolderPath = AppData.GetFolder("Data", true); _assetsFolderPath = dataFolderPath + "Assets/"; if (assetLoader == null) assetLoader = new AssetLoader(new HttpClient(), dataFolderPath, false); var skillTreeTask = LoadTreeFileAsync(dataFolderPath + "Skilltree.txt", () => assetLoader.DownloadSkillTreeToFileAsync()); var optsTask = LoadTreeFileAsync(dataFolderPath + "Opts.txt", () => assetLoader.DownloadOptsToFileAsync()); await Task.WhenAny(skillTreeTask, optsTask); controller?.SetProgress(0.1); var skillTreeObj = await skillTreeTask; var optsObj = await optsTask; controller?.SetProgress(0.25); var tree = new SkillTree(persistentData, dialogCoordinator); await tree.InitializeAsync(skillTreeObj, optsObj, controller, assetLoader); return tree; }
public Item(IPersistentData persistentData, JObject val, ItemSlot itemSlot = ItemSlot.Unequipable, bool isGem = false) { JsonBase = val; Slot = itemSlot; Width = val["w"].Value <int>(); Height = val["h"].Value <int>(); if (val["x"] != null) { X = val["x"].Value <int>(); } if (val["y"] != null) { Y = val["y"].Value <int>(); } if (val["name"] != null) { NameLine = FilterJsonString(val["name"].Value <string>()); } JToken iconToken; if (val.TryGetValue("icon", out iconToken)) { _iconUrl = iconToken.Value <string>(); } Frame = (FrameType)val["frameType"].Value <int>(); TypeLine = FilterJsonString(val["typeLine"].Value <string>()); if (isGem) { // BaseType will be null for socketed gems. _itemGroup = ItemGroup.Gem; } else { if (Frame == FrameType.Magic) { _baseType = persistentData.EquipmentData.ItemBaseFromTypeline(TypeLine); } else { persistentData.EquipmentData.BaseDictionary.TryGetValue(TypeLine, out _baseType); } // For known bases, images are only downloaded if the item is unique. All other items should always // have the same image. (except alt art non-uniques that are rare enough to be ignored) var loadImageFromIconUrl = _iconUrl != null && (_baseType == null || Frame == FrameType.Unique); if (_baseType == null) { _baseType = new ItemBase(persistentData.Options, itemSlot, TypeLine, _keywords == null ? "" : _keywords.FirstOrDefault(), Frame); } _itemType = BaseType.ItemType; _itemGroup = BaseType.ItemGroup; if (loadImageFromIconUrl) { _image = new ItemImageFromOfficial(_baseType.Image, _iconUrl); } else { _image = _baseType.Image; _image.DownloadMissingImage(); } FixOldItems(); } if (val["properties"] != null) { foreach (var obj in val["properties"]) { Properties.Add(ItemModFromJson(obj, false)); } if (Properties.Any(m => !m.Value.Any())) { // The name of one property of gems contains the Keywords of that gem. _keywords = Properties.First(m => !m.Value.Any()).Attribute.Split(',').Select(i => i.Trim()).ToList(); } } if (val["requirements"] != null) { var mods = val["requirements"].Select(t => ItemModFromJson(t, true)).ToList(); if (!mods.Any(m => m.Attribute.StartsWith("Requires "))) { var modsToMerge = new [] { mods.FirstOrDefault(m => m.Attribute == "Level #"), mods.FirstOrDefault(m => m.Attribute == "# Str"), mods.FirstOrDefault(m => m.Attribute == "# Dex"), mods.FirstOrDefault(m => m.Attribute == "# Int") }.Where(m => m != null).ToList(); modsToMerge.ForEach(m => mods.Remove(m)); mods.Add(new ItemMod(_itemType, "Requires " + string.Join(", ", modsToMerge.Select(m => m.Attribute))) { Value = modsToMerge.Select(m => m.Value).Flatten().ToList(), ValueColor = modsToMerge.Select(m => m.ValueColor).Flatten().ToList() }); } _requirements.AddRange(mods); } if (val["implicitMods"] != null) { foreach (var s in val["implicitMods"].Values <string>()) { _implicitMods.Add(new ItemMod(_itemType, s, Numberfilter)); } } if (val["explicitMods"] != null) { foreach (var s in val["explicitMods"].Values <string>()) { ExplicitMods.Add(new ItemMod(_itemType, s, Numberfilter)); } } if (val["craftedMods"] != null) { foreach (var s in val["craftedMods"].Values <string>()) { CraftedMods.Add(new ItemMod(_itemType, s, Numberfilter)); } } if (val["flavourText"] != null) { FlavourText = string.Join("\r\n", val["flavourText"].Values <string>().Select(s => s.Replace("\r", ""))); } if (isGem) { switch (val["colour"].Value <string>()) { case "S": _keywords.Add("Strength"); break; case "D": _keywords.Add("Dexterity"); break; case "I": _keywords.Add("Intelligence"); break; } } else { _gems = new List <Item>(); } var sockets = new List <int>(); if (val["sockets"] != null) { foreach (var obj in (JArray)val["sockets"]) { sockets.Add(obj["group"].Value <int>()); } } if (val["socketedItems"] != null) { int socket = 0; foreach (JObject obj in (JArray)val["socketedItems"]) { var item = new Item(persistentData, obj, isGem: true) { _socketGroup = sockets[socket++] }; _gems.Add(item); } } }