Update load icon from multi sprite file, default icon slot

This commit is contained in:
HungDK
2025-09-25 14:07:38 +07:00
parent aa543dd715
commit 1d348f3ac6
2 changed files with 84 additions and 30 deletions
@@ -199,22 +199,6 @@ namespace PerfectWorld.Scripts.Managers
}
private byte GetDefaultEquipLocation(int templateId)
{
// Basic equip location mapping based on template ID
// Adjust these ranges based on your game's item system
if (templateId >= 1000 && templateId < 2000) return 0; // Weapon
if (templateId >= 2000 && templateId < 3000) return 2; // Armor
if (templateId >= 3000 && templateId < 4000) return 3; // Accessory
if (templateId >= 4000 && templateId < 5000) return 4; // Ring
if (templateId >= 5000 && templateId < 6000) return 5; // Necklace
// Default to slot 1 if no specific mapping
Debug.Log($"[InventoryUI] Using default equip location 1 for template {templateId}");
return 0;
}
private int FindEmptyInventorySlot()
{
var inventoryData = model.GetInventoryData(PKG_INVENTORY);
@@ -270,6 +254,8 @@ namespace PerfectWorld.Scripts.Managers
// === MVC: View ===
private class InventoryView
{
private static readonly Dictionary<Image, Sprite> _defaultSprites = new Dictionary<Image, Sprite>();
public void RenderPackage(List<Button> buttons, Dictionary<int, InventoryItemData> items, byte package, System.Action<byte, int> onClick, System.Func<int, InventoryItemData, string> getDisplayText)
{
if (buttons == null)
@@ -294,18 +280,23 @@ namespace PerfectWorld.Scripts.Managers
var image = button.GetComponent<Image>();
if (image != null)
{
// Store the default sprite if we haven't seen this image before
if (!_defaultSprites.ContainsKey(image))
{
_defaultSprites[image] = image.sprite;
}
// Set icon sprite based on item TemplateId
if (hasItem && itemData != null && itemData.Count > 0)
{
var sprite = EC_IvtrItem.ResolveItemIconSprite(itemData.TemplateId);
image.sprite = sprite;
image.color = sprite != null ? Color.white : Color.white;
image.enabled = true;
}
else
{
image.sprite = null;
image.color = Color.white;
// Restore the default sprite instead of setting to null
image.sprite = _defaultSprites[image];
image.enabled = true;
}
}
@@ -29,12 +29,14 @@ namespace PerfectWorld.Scripts.Managers
private static readonly Dictionary<int, int> _pileLimitCache = new Dictionary<int, int>();
private static readonly Dictionary<int, string> _tidIconKeyCache = new Dictionary<int, string>();
private static readonly Dictionary<string, Sprite> _iconSpriteCache = new Dictionary<string, Sprite>(StringComparer.OrdinalIgnoreCase);
private static Sprite[] _multiSpriteAtlas = null;
private static readonly Dictionary<string, int> _spriteNameToIndexCache = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
private const int MaxContentHexToLog = 64;
public static string ResolveItemName(int templateId)
{
if (templateId <= 0) return "";
if (_tidNameCache.TryGetValue(templateId, out var cached)) return cached;
//if (_tidNameCache.TryGetValue(templateId, out var cached)) return cached;
try
{
var edm = ElementDataManProvider.GetElementDataMan();
@@ -104,18 +106,79 @@ namespace PerfectWorld.Scripts.Managers
private static Sprite LoadIconSpriteByKey(string key)
{
if (string.IsNullOrEmpty(key)) return null;
// Resources path without extension
string resPath = $"UI/IconSprites/{key}";
var sprite = Resources.Load<Sprite>(resPath);
if (sprite == null)
// Load multi-sprite atlas if not already loaded
if (_multiSpriteAtlas == null)
{
// Try lowercase/uppercase variants or zero-stripped variants as a fallback
var alt = Resources.Load<Sprite>($"UI/IconSprites/{key.ToLowerInvariant()}");
if (alt != null) return alt;
alt = Resources.Load<Sprite>($"UI/IconSprites/{key.ToUpperInvariant()}");
if (alt != null) return alt;
LoadMultiSpriteAtlas();
}
if (_multiSpriteAtlas == null) return null;
// Try to find sprite by name in the atlas
if (_spriteNameToIndexCache.TryGetValue(key, out var index))
{
if (index >= 0 && index < _multiSpriteAtlas.Length)
{
return _multiSpriteAtlas[index];
}
}
// Fallback: try to find by name directly in the atlas
foreach (var sprite in _multiSpriteAtlas)
{
if (sprite != null && string.Equals(sprite.name, key, StringComparison.OrdinalIgnoreCase))
{
return sprite;
}
}
// Try lowercase/uppercase variants as fallback
foreach (var sprite in _multiSpriteAtlas)
{
if (sprite != null && (string.Equals(sprite.name, key.ToLowerInvariant(), StringComparison.OrdinalIgnoreCase) ||
string.Equals(sprite.name, key.ToUpperInvariant(), StringComparison.OrdinalIgnoreCase)))
{
return sprite;
}
}
return null;
}
private static void LoadMultiSpriteAtlas()
{
try
{
// Load the multi-sprite atlas from Resources
var atlasSprites = Resources.LoadAll<Sprite>("UI/IconSprites/iconlist_ivtrm_multisprite");
if (atlasSprites != null && atlasSprites.Length > 0)
{
_multiSpriteAtlas = atlasSprites;
// Build name-to-index cache for faster lookups
_spriteNameToIndexCache.Clear();
for (int i = 0; i < atlasSprites.Length; i++)
{
if (atlasSprites[i] != null && !string.IsNullOrEmpty(atlasSprites[i].name))
{
_spriteNameToIndexCache[atlasSprites[i].name] = i;
}
}
Debug.Log($"[Inventory] Loaded multi-sprite atlas with {atlasSprites.Length} sprites");
}
else
{
Debug.LogWarning("[Inventory] Failed to load multi-sprite atlas: iconlist_ivtrm_multisprite");
_multiSpriteAtlas = new Sprite[0]; // Prevent repeated loading attempts
}
}
catch (Exception ex)
{
Debug.LogError($"[Inventory] Error loading multi-sprite atlas: {ex.Message}");
_multiSpriteAtlas = new Sprite[0]; // Prevent repeated loading attempts
}
return sprite;
}
private static object TryFindElementByScanningArrays(object edm, uint id)