ESO UI API Patch Highlights (V100026)
A summary of important changes to the ESO UI API in this package.
A number of improvements have been made to the trading house this patch. The first is the addition of a server-side text filter (TRADING_HOUSE_FILTER_TYPE_NAME_HASH). Here is how the text search process works:
- The player enters text into the search field.
- MatchTradingHouseItemNames(searchText) is called. It returns an id for a background task that will collect all of the items that contain searchText in their name (only items that could possibly be posted on the trading house). The one caveat to this is that equipment that can show enchants in its name (e.g. Rubedite Axe of Frost) will not have variations for each enchant. There will instead just be the base name (e.g. Rubedite Axe). This is to prevent an explosion of possible items in the search files. However, you can still use the enchant filter to find specific enchanted versions of items.
- Some frames later EVENT_MATCH_TRADING_HOUSE_ITEM_NAMES_COMPLETE is sent and you can then query the results using GetNumMatchTradingHouseItemNamesResults(taskId) and GetMatchTradingHouseItemNamesResult(taskId, index). Each result includes the formatted name of the item and also a 32-bit “hash value” that can be used with to get items from the server that have this same item name. When there is more than one match (for example, searching for something generic like “Glyph”) you can send multiple name hash values to include each possible item in the results.
- A search filter is then setup using SetTradingHouseFilter(TRADING_HOUSE_FILTER_TYPE_NAME_HASH, …) where … represents “hash values”. SetTradingHouseFilter now takes an arbitrary number of filter values to support text searching, but we still limit the amount that are sent to the server. The limit is 32 for every filter except name hash whose limit is controlled by a server setting. It will be initially set to 550, but it can change at any time. You can check how many filter values are allowed using GetMaxTradingHouseFilterExactTerms(filterType).
- Finally, the search is executed and the results are returned. The speed of the search will depend on the number of name hash values sent, with more hashes making the search take longer.
It is worth noting that the results of the text search are culled down by the other selected filters. For example, searching for “rubedite” with the Materials category selected will only pull up rubedite ore and rubedite ingots in the Match results. Also, placing the search term in quotes will only match that item name exactly, which is useful when the item you want is a substring of another item like “soul gem” and “soul gem (empty)”.
Another change we made was improving the behavior of timeouts in the trading house. Each search will now be given an ID, which is used to guarantee that only results from the most recent search are handled by the game client. This means that if results from a timed out search do show up later, they will not stomp the current search results. Also, when you do a trading house search, the 3 second timeout will start counting as soon as the search is requested - not when the search completes - as it was before. This solves a problem where an old search completes after the timeout but 3 seconds or less before your new search arrives, causing the new search to fail. Finally, a timeout is now sent through its own event, EVENT_TRADING_HOUSE_RESPONSE_TIMEOUT, since it is divorced from the request flow (a timeout does not stop a pending search).
Below are some smaller changes to the system and API:
- We have added a new sort type (TRADING_HOUSE_SORT_SALE_PRICE_PER_UNIT) and removed the sort type for required level.
- Trading house filters have been refactored into categories and features. See TradingHouseCategories_Shared.lua for more info.
- The ENCHANTMENT_SEARCH_CATEGORY_OTHER has been replaced with ENCHANTMENT_SEARCH_CATEGORY_PRISMATIC_DEFENSE, and ENCHANTMENT_SEARCH_CATEGORY_PRISMATIC_ONSLAUGHT.
- Other New APIs:
- GetTradingHouseSearchResultsInfo() - numItemsOnPage, currentPage, hasMorePages.
- AreAllTradingHouseSearchResultsPurchased() – allPurchased.
- HasTradingHouseListings() – hasListings.
- IsItemSellableOnTradingHouse(bagId, slotIndex) – canBeSold.
- ConvertItemGlyphTierRangeToRequiredLevelRange(isChampionRank, minTierLevel, maxTierLevel) - minRequiredLevel, maxRequiredLevel.
The zone stories system provides a way to view, track the completion of, and locate activities on a zone-by-zone basis. These are the types of activities tracked by the zone stories system:
PRIORITY_QUESTS refers to a subset of quest in a zone that have been selected as being important to the progression of the zone’s story line.
Quests associated with zone stories get their own set of visually distinctive pins on the world map:
Pins for a nearby quest giver that is part of a zone story:
A pin for the POI completion objective currently tracked through zone stories:
A pin to denote that the objective currently tracked through Zone Guide is somewhere inside an area:
An animated pin used to draw attention to relevant quest pins when using the quest journal’s Show On Map feature:
An animated pin used to draw attention to a pin when using auto map navigation, which pans and zooms the map through multiple layers to show how to get to a destination:
Next are the new APIs added for zone stories:
- GetJournalQuestZoneStoryZoneId(journalQuestIndex) – zoneId.
- GetNextZoneStoryZoneId(lastZoneId) – nextZoneId.
- GetNumZoneActivitiesForZoneCompletionType(zoneId, zoneCompletionType) - numActivities.
- For a given zone and zone completion type, returns the minimum total number of activities there are to complete, regardless of if the branches are currently blocked by an unmet requirement.
- GetNumUnblockedZoneStoryActivitiesForZoneCompletionType(zoneId, zoneCompletionType) - numUnblockedActivities, blockingBranchErrorStringId.
- For a given zone and zone completion type, returns the number of activities that can be completed before some requirement must be met to unblock further activities.
- DoesZoneCompletionTypeInZoneHaveBranchesWithDifferentLengths(zoneId, zoneCompletionType) – hasBranchesWithDifferentLengths.
- For a given zone and zone completion type, returns whether or not the given completion type may have a variable number of possible activities to complete based on a player’s actions/choices.
- GetZoneActivityIdForZoneCompletionType(zoneId, zoneCompletionType, activitiyIndex) – activityId.
- Returns an activity id for the given completion type and activity index. What the activity means is based on the zone completion type.
- GetNumCompletedZoneActivitiesForZoneCompletionType(zoneId, zoneCompletionType) – numCompletedActivities.
- GetNumAssociatedAchievementsForZoneCompletionType(zoneId, zoneCompletionType) – numAssociatedAchievements.
- For a given zone and zone completion type, returns how many achievements are directly related to the activities.
- GetAssociatedAchievementIdForZoneCompletionType(zoneId, zoneCompletionType, associatedAchievementIndex) – associatedAchievementId.
- IsZoneStoryActivityComplete(zoneId, zoneCompletionType, activityIndex) – isActivityComplete.
- GetNormalizedPositionForZoneStoryActivityId(zoneId, zoneCompletionType, activityId) - normalizedX, normalizedZ, normalizedRadius, isInCurrentMap.
- TrackNextActivityForZoneStory(zoneId, zoneCompletionType, setAutoMapNavigationTarget) – foundActivityToTrack.
- Sets the next unblocked activity for a given zone (and optionally for a specific completion type) as tracked. If the type of activity is completing a POI, it will always favor POIs closer to the player position. If the chosen POI requires a quest to complete and that quest is in the journal, it will set that quest as active instead. If the type of activity is a quest itself, it will prioritize quests already in the journal over the order specified in the Zone Guide and set that quest as active. If setAutoMapNavigationTarget is true, the map will automatically open and do an animation to show the player how to reach their destination.
- IsZoneStoryActivelyTracking() – isActivelyTracking.
These are the relevant events for zone stories:
- EVENT_ZONE_STORY_QUEST_ACTIVITY_TRACKED (questIndex)
- Event triggered when a zone story activity becomes tracked and it is a quest in the player’s journal.
Below are some miscellaneous APIs that were added:
- GetUnitWorldPosition(unitTag) - zoneId, worldX, worldY, worldZ.
- Works for the same unit tags as GetMapPlayerPosition.
- GetCurrentMapId() – mapId.
- GetMapNumTilesForMapId(mapId) – numHorizontalTiles, numVerticalTiles,
- GetMapTileTextureForMapId(mapId, tileIndex) – tileFilename.
- GetEnchantSearchCategoryType(enchantId) – searchCategory.
- GetEnchantProcAbilityId(enchantId) – abilityId.
- GetItemLinkTraitType(itemLink) – itemTraitType.
- GetItemLinkDefaultEnchantId(itemLink) – enchantId.
- GetItemLinkAppliedEnchantId(itemLink) – enchantId.
- GetItemLinkFinalEnchantId(itemLink) – enchantId.
- GetAddOnRootDirectoryPath(addOnIndex) – directoryPath.
- GetAddOnVersion(addOnIndex) – version.