Skip to content

Commit

Permalink
Added named items collection
Browse files Browse the repository at this point in the history
Added named items overlay (experimental)
Improved startup time
Updated preset for 2560 x 1440
  • Loading branch information
josdemmers committed Feb 21, 2023
1 parent 3bcb03e commit b4a1b2c
Show file tree
Hide file tree
Showing 27 changed files with 1,029 additions and 50 deletions.
4 changes: 2 additions & 2 deletions NewWorldCompanion.Constants/EmguConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ public class EmguConstants
public const int Default1600900AreaUpper = 7000;
public const int Default19201080AreaLower = 6000;
public const int Default19201080AreaUpper = 8000;
public const int Default25601440AreaLower = 10000;
public const int Default25601440AreaUpper = 15000;
public const int Default25601440AreaLower = 13000;
public const int Default25601440AreaUpper = 15500;
public const int Default38402160AreaLower = 22600;
public const int Default38402160AreaUpper = 26600;

Expand Down
2 changes: 2 additions & 0 deletions NewWorldCompanion.Entities/ItemDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@ public class ItemDefinition
public string Name { get; set; } = string.Empty;
/// <value>Used to define if an item is tradable</value>
public bool BindOnPickup { get; set; } = false;
public bool BindOnEquip { get; set; } = false;

}
}
15 changes: 15 additions & 0 deletions NewWorldCompanion.Entities/SettingsNWC.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class SettingsNWC
// Overlay
public bool TooltipEnabled { get; set; } = true;
public bool ExtendedTooltipEnabled { get; set; } = false;
public bool NamedItemsTooltipEnabled { get; set; } = false;
public int PriceServerId { get; set; } = 1;

// Shape detection
Expand All @@ -28,5 +29,19 @@ public class SettingsNWC
public int EmguThresholdMaxR { get; set; } = 200;
public int EmguThresholdMaxG { get; set; } = 235;
public int EmguThresholdMaxB { get; set; } = 255;

// Named items
public bool NamedItemsFilterTier2 { get; set; } = true;
public bool NamedItemsFilterTier3 { get; set; } = true;
public bool NamedItemsFilterTier4 { get; set; } = true;
public bool NamedItemsFilterTier5 { get; set; } = true;
public bool NamedItemsFilterItemClassArmor { get; set; } = true;
public bool NamedItemsFilterItemClassJewelry { get; set; } = true;
public bool NamedItemsFilterItemClassWeapon { get; set; } = true;
public bool NamedItemsFilterStorageCollected { get; set; } = true;
public bool NamedItemsFilterStorageMissing { get; set; } = true;
public bool NamedItemsFilterStorageDuplicates { get; set; } = true;
public bool NamedItemsFilterBindOnEquip { get; set; } = true;
public bool NamedItemsFilterBindOnPickup { get; set; } = true;
}
}
5 changes: 5 additions & 0 deletions NewWorldCompanion.Events/ScreenCaptureEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,9 @@ public class ScreenCaptureReadyEvent : PubSubEvent
public class MouseCoordinatesUpdatedEvent : PubSubEvent
{
}

public class MouseDeltaUpdatedEvent : PubSubEvent<double>
{

}
}
8 changes: 8 additions & 0 deletions NewWorldCompanion.Events/StorageManagerEvents.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Prism.Events;

namespace NewWorldCompanion.Events
{
public class StorageManagerUpdated : PubSubEvent
{
}
}
4 changes: 4 additions & 0 deletions NewWorldCompanion.Interfaces/INewWorldDataStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,18 @@ public interface INewWorldDataStore
string LoadStatusCraftingRecipes { get; }
string LoadStatusHouseItems { get; }
string LoadStatusLocalisation { get; }
string LoadStatusLocalisationNamed { get; }

List<CraftingRecipe> GetCraftingRecipes();
bool IsBindOnPickup(string itemName);
bool IsNamedItem(string itemName);
string GetItemId(string itemName);
ItemDefinition? GetItem(string itemId);
string GetLevenshteinItemName(string itemName);
List<MasterItemDefinitionsJson> GetOverlayResources();
List<NamedItem> GetNamedItems();
string GetItemLocalisation(string itemMasterName);
string GetNamedItemLocalisation(string itemMasterName);
List<CraftingRecipeJson> GetRelatedRecipes(string itemId);
CraftingRecipeJson GetCraftingRecipeDetails(string itemId);
void UpdateStoreData();
Expand Down
1 change: 1 addition & 0 deletions NewWorldCompanion.Interfaces/IStorageManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ ObservableCollection<Item> Items
get;
}

string GetItemStorageInfo(string itemName);
void SaveStorage();
}
}
93 changes: 78 additions & 15 deletions NewWorldCompanion.Services/NewWorldDataStore.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using NewWorldCompanion.Constants;
using Microsoft.Extensions.Logging;
using NewWorldCompanion.Constants;
using NewWorldCompanion.Entities;
using NewWorldCompanion.Events;
using NewWorldCompanion.Helpers;
using NewWorldCompanion.Interfaces;
using Prism.Events;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
Expand All @@ -21,29 +23,36 @@ namespace NewWorldCompanion.Services
public class NewWorldDataStore : INewWorldDataStore
{
private readonly IEventAggregator _eventAggregator;
private readonly ILogger _logger;

private List<MasterItemDefinitionsJson> _masterItemDefinitionsJson = new List<MasterItemDefinitionsJson>();
private List<MasterItemDefinitionsJson> _masterItemDefinitionsJson_Named = new List<MasterItemDefinitionsJson>();
private List<CraftingRecipeJson> _craftingRecipesJson = new List<CraftingRecipeJson>();
private List<HouseItemsJson> _houseItemsJson = new List<HouseItemsJson>();
private Dictionary<string, string> _itemDefinitionsLocalisation = new Dictionary<string, string>();
private ConcurrentDictionary<string, string> _itemDefinitionsLocalisation = new ConcurrentDictionary<string, string>(50, 15000);
private ConcurrentDictionary<string, string> _namedItemDefinitionsLocalisation = new ConcurrentDictionary<string, string>(50, 15000);

private bool _available = false;

private string _loadStatusItemDefinitions = string.Empty;
private string _loadStatusCraftingRecipes = string.Empty;
private string _loadStatusHouseItems = string.Empty;
private string _loadStatusLocalisation = string.Empty;
private string _loadStatusLocalisationNamed = string.Empty;


// Start of Constructor region

#region Constructor

public NewWorldDataStore(IEventAggregator eventAggregator)
public NewWorldDataStore(IEventAggregator eventAggregator, ILogger<NewWorldDataStore> logger)
{
// Init IEventAggregator
_eventAggregator = eventAggregator;

// Init logger
_logger = logger;

// Init store data
Task.Run(() => UpdateStoreData());
}
Expand All @@ -59,6 +68,7 @@ public NewWorldDataStore(IEventAggregator eventAggregator)
public string LoadStatusCraftingRecipes { get => _loadStatusCraftingRecipes; set => _loadStatusCraftingRecipes = value; }
public string LoadStatusHouseItems { get => _loadStatusHouseItems; set => _loadStatusHouseItems = value; }
public string LoadStatusLocalisation { get => _loadStatusLocalisation; set => _loadStatusLocalisation = value; }
public string LoadStatusLocalisationNamed { get => _loadStatusLocalisationNamed; set => _loadStatusLocalisationNamed = value; }

#endregion

Expand All @@ -73,8 +83,10 @@ public void UpdateStoreData()
_loadStatusItemDefinitions = $"ItemDefinitions: 0. Loading common items";
_eventAggregator.GetEvent<NewWorldDataStoreStatusUpdated>().Publish();

// MasterItemDefinitions Common
_masterItemDefinitionsJson.Clear();
_masterItemDefinitionsJson_Named.Clear();

// MasterItemDefinitions Common
var masterItemDefinitionsJson = new List<MasterItemDefinitionsJson>();
resourcePath = @".\Data\MasterItemDefinitions_Common.json";
using (FileStream? stream = File.OpenRead(resourcePath))
Expand Down Expand Up @@ -164,6 +176,7 @@ public void UpdateStoreData()

masterItemDefinitionsJson = JsonSerializer.Deserialize<List<MasterItemDefinitionsJson>>(stream, options) ?? new List<MasterItemDefinitionsJson>();
_masterItemDefinitionsJson.AddRange(masterItemDefinitionsJson);
_masterItemDefinitionsJson_Named.AddRange(masterItemDefinitionsJson);
}
}

Expand Down Expand Up @@ -232,6 +245,7 @@ public void UpdateStoreData()

_loadStatusHouseItems = $"HouseItems: {_houseItemsJson.Count}";
_loadStatusLocalisation = $"Localisation: 0. Loading localisations";
_loadStatusLocalisationNamed = $"Localisation (named): 0. Loading localisations";
_eventAggregator.GetEvent<NewWorldDataStoreStatusUpdated>().Publish();

// ItemDefinitionsLocalisation - Itemdefinitions
Expand All @@ -246,7 +260,8 @@ public void UpdateStoreData()
where loc.Name.LocalName == "string"
select loc;

foreach (var loc in query)
Parallel.ForEach(query, new ParallelOptions { MaxDegreeOfParallelism = 50 },
loc =>
{
string key = loc.Attribute("key")?.Value ?? string.Empty;
string value = loc.Value;
Expand All @@ -255,22 +270,31 @@ public void UpdateStoreData()
// MasterItemDefinitions_Common.json
// MasterItemDefinitions_Crafting.json
// MasterItemDefinitions_Loot.json
// MasterItemDefinitions_Named.json
// MasterItemDefinitions_Quest.json
if (_masterItemDefinitionsJson.Any(d => d.Name?.Equals("@" + key, StringComparison.OrdinalIgnoreCase) ?? false))
{
_itemDefinitionsLocalisation.TryAdd(key.ToLower(), value);
}
if (_masterItemDefinitionsJson_Named.Any(d => (d.Name?.Equals("@" + key, StringComparison.OrdinalIgnoreCase) ?? false) && d.ItemClass.Contains("Named")))
{
_namedItemDefinitionsLocalisation.TryAdd(key.ToLower(), value);
}

_loadStatusLocalisation = $"Localisation data: {_itemDefinitionsLocalisation.Count}";
_loadStatusLocalisationNamed = $"Localisation data (named): {_namedItemDefinitionsLocalisation.Count}";
_eventAggregator.GetEvent<NewWorldDataStoreStatusUpdated>().Publish();
}
});
}
}

// ItemDefinitionsLocalisation - Itemdefinitions - Cleanup duplicates
_itemDefinitionsLocalisation.Remove("ArrowBT2_MasterName".ToLower());
_itemDefinitionsLocalisation.Remove("ArrowBT4_MasterName".ToLower());
_itemDefinitionsLocalisation.Remove("ArrowBT5_MasterName".ToLower());
_itemDefinitionsLocalisation.Remove("ArrowBT2_MasterName".ToLower(), out string? _);
_itemDefinitionsLocalisation.Remove("ArrowBT4_MasterName".ToLower(), out string? _);
_itemDefinitionsLocalisation.Remove("ArrowBT5_MasterName".ToLower(), out string? _);
// ItemDefinitionsLocalisation - Itemdefinitions - Cleanup resource / item conflicts
// TODO: Remove workaround when named items are separated.
_itemDefinitionsLocalisation.Remove("2hGreatSword_FlintT5_MasterName".ToLower(), out string? _);

// ItemDefinitionsLocalisation - HouseItems
resourcePath = @".\Data\javelindata_housingitems.loc.xml";
Expand All @@ -283,7 +307,9 @@ public void UpdateStoreData()
where loc.Name.LocalName == "string"
select loc;

foreach (var loc in query)
//foreach (var loc in query)
Parallel.ForEach(query, new ParallelOptions { MaxDegreeOfParallelism = 50 },
loc =>
{
string key = loc.Attribute("key")?.Value ?? string.Empty;
string value = loc.Value;
Expand All @@ -297,7 +323,7 @@ public void UpdateStoreData()

_loadStatusLocalisation = $"Localisation data: {_itemDefinitionsLocalisation.Count}";
_eventAggregator.GetEvent<NewWorldDataStoreStatusUpdated>().Publish();
}
});
}
}

Expand Down Expand Up @@ -417,8 +443,10 @@ public List<NamedItem> GetNamedItems()
{
ItemClass = masterItem.ItemClass,
ItemID = masterItem.ItemID,
Localisation = GetItemLocalisation(masterItem.Name),
Tier = masterItem.Tier
Localisation = GetNamedItemLocalisation(masterItem.Name),
Tier = masterItem.Tier,
BindOnEquip = masterItem.BindOnEquip,
BindOnPickup = masterItem.BindOnPickup
});
}

Expand All @@ -441,7 +469,37 @@ public bool IsBindOnPickup(string itemName)
return true;
}

public string GetItemId(string itemName)
public bool IsNamedItem(string itemName)
{
//var localisationId = _itemDefinitionsLocalisation.FirstOrDefault(x => x.Value.Replace("\\n", " ").Equals(itemName, StringComparison.OrdinalIgnoreCase)).Key;
//var item = _masterItemDefinitionsJson.FirstOrDefault(i => i.Name.Equals($"@{localisationId}", StringComparison.OrdinalIgnoreCase));

// TODO: Remove workaround when there is an alternative overlay for named items.
var localisationIds = _itemDefinitionsLocalisation.Where(x => x.Value.Replace("\\n", " ").Equals(itemName, StringComparison.OrdinalIgnoreCase));
if (localisationIds.Count() == 0)
{
return false;
}
else
{
_logger.LogWarning($"Item: {itemName} is not unique. There are {localisationIds.Count()} entries found");
}

// Check all similar named items. If one of them is not "named" return false.
// Workaround need for weapon and resource that both share the name "Flint".
bool uniqueNamedItem = true;
foreach (var localisationId in localisationIds)
{
var item = _masterItemDefinitionsJson.FirstOrDefault(i => i.Name.Equals($"@{localisationId.Key}", StringComparison.OrdinalIgnoreCase));
if (!item.ItemClass.Contains("Named"))
{
uniqueNamedItem = false;
}
}
return uniqueNamedItem;
}

public string GetItemId(string itemName)//
{
var localisationId = _itemDefinitionsLocalisation.FirstOrDefault(x => x.Value.Replace("\\n", " ").Equals(itemName, StringComparison.OrdinalIgnoreCase)).Key;
MasterItemDefinitionsJson? item = _masterItemDefinitionsJson.FirstOrDefault(i => i.Name.Equals($"@{localisationId}", StringComparison.OrdinalIgnoreCase));
Expand Down Expand Up @@ -491,14 +549,19 @@ public string GetLevenshteinItemName(string itemName)
Debug.WriteLine($"Levenshtein. Item: {itemName}, Match: {currentItem}, Distance: {currentDistance}");

//return currentDistance <= Math.Max(3, itemName.Length) ? currentItem : itemName;
return currentDistance <= 3 ? currentItem : itemName;
return currentDistance <= 5 ? currentItem : itemName;
}

public string GetItemLocalisation(string itemMasterName)
{
return _itemDefinitionsLocalisation.GetValueOrDefault(itemMasterName.Trim(new char[] { '@' }).ToLower()) ?? itemMasterName.Trim(new char[] { '@' });
}

public string GetNamedItemLocalisation(string itemMasterName)
{
return _namedItemDefinitionsLocalisation.GetValueOrDefault(itemMasterName.Trim(new char[] { '@' }).ToLower()) ?? itemMasterName.Trim(new char[] { '@' });
}

public List<CraftingRecipeJson> GetRelatedRecipes(string itemId)
{
// Note: The following recipes are ignored:
Expand Down
Loading

0 comments on commit b4a1b2c

Please sign in to comment.