View Single Post
05/22/17, 10:32 AM   #1
sirinsidiator
 
sirinsidiator's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 1,578
[implemented] Guild Kiosks

A while ago I added a new feature to AwesomeGuildStore which automatically generates a list of every guild kiosk in the game and when a player visits the NPC it remembers the guild owner.
This is currently language dependent and basically only works in English, because the kiosks are tracked by the NPC name and map name and guild names are parsed from strings.

With Morrowind out of the door I figured I'd summarize what I currently do to achieve this and what API additions I would like to see in order to simplify the feature and make it work more robustly.

There are 3 different data sets I collect.
  • store data - is basically a location where one or more kiosks are. This uses a combination of the map name and location index as an identifier and contains infos on how to find the specific location (e.g. when I want to show it on the map) and also which kiosks are there.
  • kiosk data - uses the NPC name as an id and simply contains the last visit time, exact coordinates and a reference to the store location.
  • owner data - maps a guild name to a kiosk id for every week

1) Getting all stores and kiosks
This currently works by iterating over all zone and city maps and looking through all location pins for the desired type.
When switching to a zone map, it iterates over all location pins and checks for guild kiosks by comparing the icon.
Then it steps into each city map by iterating over all POIs and using ProcessMapClick on them and repeating the same function used to get kiosks on a zone map.
It collects the kiosk from the location tooltips, but there are several problems:
  • For kiosks in outlaw refuges it cannot get the NPC name from the tooltip as it is not shown. The thieves guild in Hew's Bane however does show the name of the trader inside.
  • The kiosks in Kvatch (Gold Coast) and in some outlaw refuges do not have a dedicated kiosk icon, but instead are shown as part of another tooltip.
  • Some NPC names on the kiosk tooltips are incorrect (e.g. one of the traders shown on the tooltip in wayrest is actually in elden root irc).
  • For some outlaw refuges the name on the location tooltip on the city map is not the same as the map name inside the refuge (e.g. "Orsinium Outlaw Refuge" vs "Orsinium Outlaws Refuge", "Vivec City Outlaws Refuge" vs "Vivec Outlaws Refuge")
  • The actual location of the individual traders can only be approximated as they all use the same location pin

2) Getting the location and guild owner
The addon scans the unit caption whenever the player looks at a different NPC and tries to parse it for the guild name.
When the guild store is opened, it will also store the exact location of the kiosk as it is not available from the outside (using the "reticleover" unittag).
For guilds that the player is a member of, the kiosk name is received via GetGuildOwnedKioskInfo to automatically update the list.

Main problems here:
  • NPCs won't give away their map location when not talked to
  • Information about the guild kiosk owners is only available from the unit caption and has to be matched when the guild store is not open
    (On a side note, the kiosk caption language is not updated when the client language is changed on the fly and only refreshes on relog)
  • Kiosk captions seem to trigger a server request when the NPC is looked at for the first time and only updates to show the guild owner when the player looks away and back to the NPC (it also sometimes takes several seconds before it finally shows up)
  • GetGuildOwnedKioskInfo returns a localized string which contains kiosk name and location, which has to be parsed in order to get the NPCs name, but different locations use different wording (e.g. a in b, a in the b, a on b, a near b). A second and third parameter to return just the kiosk and location would be really nice

3) Trading weeks
The owner data is then stored per ISO week in order to keep record of which guilds have shown up where.
The game itself does not supply the trader change time anywhere outside of the kiosk bidding dialog, so I had to hardcode the UTC time which has been announced in some forum post. I also had to write a whole library to handle timestamps and get ISO weeks from them.
The game also does not reliably update the guild information when the trader change happens and there is a delay of one or more minute before anyone knows if their bid actually made it unless they stand in front of the kiosk and open the guild store after the change.

Problems:
  • No way to get the trader change time
  • No way to work with timestamps and get ISO weeks
  • No way to reliably update info about the kiosk of joined guilds when the trader change happened

For 1 and 2 it would be ideal if there was a whole new API to get kiosk data:
Lua Code:
  1. count = GetNumGuildKiosks() -- returns the number of kiosk NPCs
  2. traderName, storeName, guildOwnerName, locationIndex, mapX, mapY = GetGuildKioskInfo(kioskIndex)
  3. -- traderName is the NPC
  4. -- storeName the name of the shop which is currently only available from GetGameCameraNonInteractableName()
  5. -- guildOwnerName is the guild name of the current owner
  6. -- locationIndex is the map location index which can be used to get the tooltip
  7. -- mapX/Y is the exact position of the NPC on the target map
  8. SetMapToGuildKiosk(kioskIndex) -- allows to directly open the target map
  9. kioskId = GetGuildKioskId(index) -- converts to a kiosk ID which identifies them independently of version and language
  10. kioskIndex = GetGuildKioskIndex(kioskId) -- allows to get the index from the id for use with SetMapToGuildKiosk and GetGuildKioskInfo
But I am also open for other ideas that make this more robust and easier to handle different languages.

For 3 it would be nice to have some more functions to work with timestamps in order to move the calculations from lua to c code. A function GetTraderChangeTime() which returns the timestamp for the next trader change on the current server and an event which gets fired at the trader change time and signals that the new owner info is now available would also be very desirable.