Maintenance for the week of March 25:
• [COMPLETE] ESO Store and Account System for maintenance – March 28, 9:00AM EDT (13:00 UTC) - 12:00PM EDT (16:00 UTC)

Update 14 API Patch Notes & Change Log (PTS)

ZOS_GinaBruno
ZOS_GinaBruno
Community Manager
ESO UI API Patch Highlights (V100019)

Battlegrounds
Battlegrounds have been added to ESO. There are a number of code concepts that support this:

Battleground Alliance
Players are randomly assigned to one of three battleground alliances when they enter the battleground. The battleground alliances are:
  • BATTLEGROUND_ALLIANCE_FIRE_DRAKES
  • BATTLEGROUND_ALLIANCE_PIT_DAEMONS
  • BATTLEGROUND_ALLIANCE_STORM_LORDS

You can query a unit’s battleground alliance with:
  • GetUnitBattlegroundAlliance(unitTag) – battlegroundAlliance
  • GetBattlegroundAllianceName(battlegroundAlliance) - name

Battleground Game Type
There are a number of battleground game types, each with their own rules and objectives:
  • BATTLEGROUND_GAME_TYPE_CAPTURE_THE_FLAG
  • BATTLEGROUND_GAME_TYPE_CRAZY_KING
  • BATTLEGROUND_GAME_TYPE_DEATHMATCH
  • BATTLEGROUND_GAME_TYPE_DOMINATION
  • BATTLEGROUND_GAME_TYPE_KING_OF_THE_HILL
  • BATTLEGROUND_GAME_TYPE_MURDERBALL
Note that of these, CAPTURE_THE_FLAG, DOMINATION, and DEATHMATCH are active for this release; other game types are in various stages of development and are subject to change or not being released.

The following functions have been added to learn about the battleground game type:
  • GetCurrentBattlegroundId() – battlegroundId
  • GetBattlegroundGameType(battlegroundId) – gameType
  • GetBattlegroundName(battlegroundId) – name
  • GetBattlegroundDescription(battlegroundId) – description
  • GetBattlegroundInfoTexture(battlegroundId) – path
  • GetScoreToWinBattleground(battlegroundId) – scoreToWin
  • GetBattlegroundNearingVictoryPercent(battlegroundId) – nearingVictoryPercent
  • GetCurrentBattlegroundScore(battlegroundAlliance) – score
  • LeaveBattleground()
  • IsActiveWorldBattleground() - isBattleground
EVENT_BATTLEGROUND_RULESET_CHANGED is sent when the game type changes. ZONE_SCORING_CHANGED is sent when the battleground score changes.

Battleground State
A battleground moves through a number of states as it goes through its lifetime. The states are:
  • BATTLEGROUND_STATE_PREGAME
    • Waiting for enough players to start.
  • BATTLEGROUND_STATE_STARTING
    • Counting down until the battleground starts.
  • BATTLEGROUND_STATE_RUNNING
    • Game is in progress.
  • BATTLEGROUND_STATE_POSTGAME
    • Game is done, counting down until players are removed.

EVENT_BATTLEGROUND_STATE_CHANGED is sent when the state changes. The query functions are:
  • GetCurrentBattlegroundState() – battlegroundState
  • IsCurrentBattlegroundStateTimed() – isTimed
  • GetCurrentBattlegroundStateTimeRemaining() – timeRemaining

Objectives
Objectives will be familiar to those who have worked with the capture areas in Cyrodiil or Imperial City. Battlegrounds make use of a number of different objective types, each with their own mechanics and state. The relevant objectives for this patch are:
  • OBJECTIVE_CAPTURE_AREA
    • Stand near a banner to capture.
    • When there are multiple of these they are distinguished by their designation. Use GetObjectiveDesignation(keepId, objectiveId, battlegroundContext) – designation.
      • OBJECTIVE_DESIGNATION_A
      • OBJECTIVE_DESIGNATION_B
      • OBJECTIVE_DESIGNATION_C
      • OBJECTIVE_DESIGNATION_D
  • OBJECTIVE_FLAG_CAPTURE
    • Pick up a flag and return it to your base to score.

Objectives have a lot of shared functionality for finding objectives and learning about them:
  • GetNumObjectives() – numObjectives
    • Number of objectives the client knows about. Will also include Cyrodiil objectives if you have a home campaign.
  • GetObjectiveIdsForIndex(index) – keepId, objectiveId, battlegroundContext
    • The three part key that uniquely identifies an objective. For battlegrounds, keepId is always 0 and battlegroundContext is BGQUERY_LOCAL. From here on these three values will be replaced with “ids” for brevity.
  • IsBattlegroundObjective(ids) - isInBattleground
  • DoesObjectiveExist(ids) – exists
  • GetObjectiveType(ids) – objectiveType
  • GetObjectiveControlState(ids) – controlState
    • There are many states an objective can be in.
      • OBJECTIVE_CONTROL_STATE_AREA_ABOVE_CONTROL_THRESHOLD
      • OBJECTIVE_CONTROL_STATE_AREA_BELOW_CONTROL_THRESHOLD
      • OBJECTIVE_CONTROL_STATE_AREA_MAX_CONTROL
      • OBJECTIVE_CONTROL_STATE_AREA_NO_CONTROL
      • OBJECTIVE_CONTROL_STATE_FLAG_AT_BASE
      • OBJECTIVE_CONTROL_STATE_FLAG_AT_ENEMY_BASE
      • OBJECTIVE_CONTROL_STATE_FLAG_DROPPED
      • OBJECTIVE_CONTROL_STATE_FLAG_HELD
  • GetObjectiveInfo(ids) – name, objectiveType, objectiveState
  • GetObjectivePinInfo(ids) – pinType, normalizedX, normalizedY, continuousUpdate
    • continuousUpdate is true if the objective moves around like a capture flag.
  • GetObjectiveSpawnPinInfo(ids) - pinType, normalizedX, normalized
    • Capture flag objectives have a spawn location in addition to the objective itself.
  • GetObjectiveAuraPinInfo(ids) – pinType, r, g, b
  • The aura pin sits behind the objective pin to give information on which team is influencing the objective. It is always at the same location as the objective pin. The r, g, b is used to color it.
  • GetObjectiveReturnPinInfo(ids) - pinType, normalizedX, normalizedY, continuousUpdate
  • Capture flag objectives are also returned to a specific location to score.

Carryable objectives such as the capture flag have carrying related APIs:
  • IsCarryableObjectiveCarriedByLocalPlayer(ids) – isCarried
  • GetCarryableObjectiveHoldingAllianceInfo(ids) – holdingAlliance, lastHoldingAlliance
  • GetCarryableObjectiveHoldingCharacterInfo(ids) – characterName, displayName, classId
  • GetCarryableObjectiveLastHoldingCharacterInfo(ids) - characterName, displayName, classId

Capture areas alone have:
  • IsCaptureAreaObjectiveCaptured(ids) – isCaptured.
  • A capture area is captured when the owning alliance is above 50% on the meter.
Capture Flags alone have:
  • GetCaptureAreaObjectiveOwner(ids) – ownerAlliance
  • GetCaptureAreaObjectiveLastInfluenceState(ids) – alliance, wereInfluenceSourcesInRangeOfCaptureArea
    • Provides information on which team is influencing an objective. Influencing means pushing the capture meter in their direction. wereInfluenceSourcesInRangeOfCaptureArea is false when no one is around. When it is true, if the alliance is NEUTRAL then there are equal numbers of players from multiple teams so no one is actively influencing the area. This information is also available for Cyrodiil.
  • GetCaptureFlagObjectiveOriginalOwningAlliance(ids) – originalOwningAlliance
    • The team that starts with control of this objective.

Objectives have a number of specific events for when they change. These are the relevant ones for this patch:
  • EVENT_CAPTURE_AREA_STATE_CHANGED
  • EVENT_CAPTURE_FLAG_STATE_CHANGED

Medals
Each battleground has a number of different medals it can award. Each medal is worth a fixed number of points and is granted when a condition is met. Querying the medals that a battleground can award is done with:
  • GetBattlegroundNumUsedMedals(battlegroundId) – numMedals
  • GetBattlegroundMedalIdByIndex(battlegroundId, medalIndex) – medalId

Learning about the medals can be done using the medalId in the following APIs:
  • GetMedalInfo(medalId) – name, textureName, iconTexture, condition, scoreReward
  • GetMedalName(medalId) – name
  • GetMedalScoreReward(medalId) – scoreReward

Finally, you can query which medals each person in a battleground has earned using the scoreboard APIs:
  • GetNextScoreboardEntryMedalId(slotIndex, lastMedalId) – nextMedalId
  • GetScoreboardEntryNumEarnedMedalsById(slotIndex, medalId) – count

When the player earns a medal EVENT_MEDAL_AWARDED is sent.

Scoreboard
The battleground scoreboard has entries for all players in the battleground. You can query its contents with:
  • GetNumScoreboardEntries() – numEntries
  • GetScoreboardPlayerEntryIndex() - playerIndex
  • GetScoreboardEntryInfo(slotIndex) – characterName, displayName, battlegroundAlliance, isLocalPlayer
  • GetScoreboardEntryBattlegroundAlliance(slotIndex) – battlegroundAlliance
  • GetScoreboardEntryClassId(slotIndex) – classId
  • GetScoreboardEntryScoreByType(slotIndex, scoreType) – score
    • This function can return information on a number of stats that we collect over the course of the battleground for each player. scoreType is one of:
      • SCORE_TRACKER_TYPE_ASSISTS
      • SCORE_TRACKER_TYPE_CAPTURE_DEFENSE_POINTS
      • SCORE_TRACKER_TYPE_CAPTURE_KILLED_ATTACKER
      • SCORE_TRACKER_TYPE_CAPTURE_KILLED_DEFENDER
      • SCORE_TRACKER_TYPE_DAMAGE_DONE
      • SCORE_TRACKER_TYPE_DAMAGE_TAKEN
      • SCORE_TRACKER_TYPE_DEATH
      • SCORE_TRACKER_TYPE_FLAG_CAPTURED
      • SCORE_TRACKER_TYPE_HEALING_DEFENDERS
      • SCORE_TRACKER_TYPE_HEALING_DONE
      • SCORE_TRACKER_TYPE_KILL
      • SCORE_TRACKER_TYPE_KILLED_FLAG_CARRIER
      • SCORE_TRACKER_TYPE_KILL_STREAK
      • SCORE_TRACKER_TYPE_SCORE

Leaderboards
The battlegrounds system includes several leaderboards ranking players by total personal score accumulated. There are presently three leaderboards, one for each battlegroundLeaderboardType (Deathmatch, Flag Games, Land Grab).
  • QueryBattlegroundLeaderboardData()
  • GetNextBattlegroundLeaderboardType(lastBattlegroundLeaderboardType) – nextBattlegroundLeaderboardType
  • GetNumBattlegroundLeaderboardEntries(battlegroundLeaderboardType) – numEntries
  • GetBattlegroundLeaderboardEntryInfo(battlegroundLeaderboardType, entryIndex) – rank, displayName, characterName, score
  • GetBattlegroundLeaderboardLocalPlayerInfo(battlegroundLeaderboardType) – currentRank, currentScore
  • GetBattlegroundLeaderboardsSchedule() – secondsUntilEnd, secondsUntilNextStart

Subscriber Bank
A new bank bag has been added to the game for ESO Plus subscribers and is named BAG_SUBSCRIBER_BANK. The size of the bag is the same as BAG_BACKPACK. We have also added a new bag function, GetBagUseableSize(bagId), to return how many usable slots a bag has. This will return 0 for the subscriber bank if the player does not have ESO Plus. This new bag also necessitated some changes in the lua inventory objects to support multiple bags appearing in a single inventory view. Look out for functions that once took inventoryType now taking bagId as an additional parameter.

Skill Discovery
Some skill lines are now hidden by default and are awarded based on completing quests or other game actions. The GetSkillLineInfo(skillType, skillIndex) API now also returns discovered to indicate if the player has discovered that skill line. EVENT_SKILL_LINE_ADDED is sent when a skill line is discovered.

Center Screen Announcements
Center screen announcements have been refactored in a few ways. Instead of supplying a long, long, long list of returns to specify all of the details of the announcement, you now return messageParams object created from CENTER_SCREEN_ANNOUNCE:CreateMessageParams(type, sounds). All of the existing functionality can be accessed by calling the appropriate functions on the messageParams object. We have also changed priority and filtering to be based on the new CENTER_SCREEN_ANNOUNCE_TYPE enum instead of events because there were more and more announcements not triggered by events. Finally, we have added two new announcement types called CSA_CATEGORY_MAJOR_TEXT and CSA_CATEGORY_COUNTDOWN_TEXT. These are used for battleground messages and countdowns (battleground start and dueling) respectively.

Compass Group Members
New settings have been added to control when group members appear on the compass. By default they only appear on the compass in battlegrounds. The settings are:
  • UI_SETTING_COMPASS_GROUP_LEADER
  • UI_SETTING_COMPASS_GROUP_MEMBER_AVA
  • UI_SETTING_COMPASS_GROUP_MEMBER_BATTLEGROUND
  • UI_SETTING_COMPASS_GROUP_MEMBER_DELVE
  • UI_SETTING_COMPASS_GROUP_MEMBER_DUNGEON
  • UI_SETTING_COMPASS_GROUP_MEMBER_GENERAL
  • UI_SETTING_COMPASS_GROUP_MEMBER_RAID
The settings can be set to either true or false.

Furnishing Materials
ITEMTYPE_FURNISHING_MATERIAL has been added to distinguish furnishing materials. We have also added specialized item types for these:
  • SPECIALIZED_ITEMTYPE_FURNISHING_MATERIAL_ALCHEMY
  • SPECIALIZED_ITEMTYPE_FURNISHING_MATERIAL_BLACKSMITHING
  • SPECIALIZED_ITEMTYPE_FURNISHING_MATERIAL_CLOTHIER
  • SPECIALIZED_ITEMTYPE_FURNISHING_MATERIAL_ENCHANTING
  • SPECIALIZED_ITEMTYPE_FURNISHING_MATERIAL_WOODWORKING

Guild Permissions
GUILD_PERMISSION_BANK_VIEW_DEPOSIT_HISTORY, GUILD_PERMISSION_BANK_VIEW_GOLD, and GUILD_PERMISSION_BANK_VIEW_WITHDRAW_HISTORY have been added but are not yet functional.

Compass Pin Colors
Compass pins can now be tinted using SetPinTint(pinType, r, g, b, param1, param2, param3)

Miscellaneous
  • JumpToSpecificHouse(displayName, houseId)
  • PreviewItemLink(itemLink, dyeBrushId)
  • GetItemLinkGrantedRecipeIndices(itemLink) – recipeListIndex, recipeIndex
Gina Bruno
Senior Community Manager
Dev Tracker | Service Alerts | ESO Twitter | My Twitter
Staff Post
  • SirBedevere
    SirBedevere
    ✭✭✭
    Guild Permissions
    GUILD_PERMISSION_BANK_VIEW_DEPOSIT_HISTORY, GUILD_PERMISSION_BANK_VIEW_GOLD, and GUILD_PERMISSION_BANK_VIEW_WITHDRAW_HISTORY have been added but are not yet functional.
    @ZOS_ChipHilseberg, is the plan for these new permissions to be functional by the time Morrowind is released?
  • nooblybear
    nooblybear
    ✭✭✭
    Guild Permissions
    GUILD_PERMISSION_BANK_VIEW_DEPOSIT_HISTORY, GUILD_PERMISSION_BANK_VIEW_GOLD, and GUILD_PERMISSION_BANK_VIEW_WITHDRAW_HISTORY have been added but are not yet functional.
    @ZOS_ChipHilseberg, is the plan for these new permissions to be functional by the time Morrowind is released?

    I'm very much looking forward to the implications this will have for trade guilds.

    Primarily, however, I am really excited about:
    JumpToSpecificHouse(displayName, houseId)

    Thank you so much!
    AddOn Developer - RIP Akaviri Union (PC-NA)
  • silvereyes
    silvereyes
    ✭✭✭✭✭
    ✭✭
    @ZOS_GinaBruno, can we post Update 14 compatibility fixes for our addons to esoui.com, or is that a breach of the NDA? I think I remember seeing language in the NDA about anything ZOS officially announces is fair game. Does that mean if our code only deals with the changes listed in the above notes, we can publish to esoui.com?
  • wiff_wacer
    wiff_wacer
    ✭✭✭
    • JumpToSpecificHouse(displayName, houseId)
    • PreviewItemLink(itemLink, dyeBrushId)
    • GetItemLinkGrantedRecipeIndices(itemLink) – recipeListIndex, recipeIndex

    Time to sacrifice another goat to Chip! One? Two!!
    ee221c0739a6ffca8d6497690508d139.jpg

    Evaluated husband sustain, nerf stamina!
  • Elsonso
    Elsonso
    ✭✭✭✭✭
    ✭✭✭✭✭
    Does anyone have any insight on the practical difference between this
    * GetBagUseableSize(*[Bag|#Bag]* _bagId_)
    ** _Returns:_ *integer* _bagSlots_
    

    ... and these?
    * GetBagSize(*[Bag|#Bag]* _bagId_)
    ** _Returns:_ *integer* _bagSlots_
    
    * GetNumBagUsedSlots(*[Bag|#Bag]* _bagId_)
    ** _Returns:_ *integer* _usedSlots_
    
    * GetNumBagFreeSlots(*[Bag|#Bag]* _bagId_)
    ** _Returns:_ *integer* _freeSlots_
    

    It seems to me that it duplicates an existing function, any way that I interpret it.
    PC NA/EU: @Elsonso
    XBox EU/NA: @ElsonsoJannus
    X/Twitter: ElsonsoJannus
  • silvereyes
    silvereyes
    ✭✭✭✭✭
    ✭✭
    Does anyone have any insight on the practical difference between this
    * GetBagUseableSize(*[Bag|#Bag]* _bagId_)
    ** _Returns:_ *integer* _bagSlots_
    

    ... and these?
    * GetBagSize(*[Bag|#Bag]* _bagId_)
    ** _Returns:_ *integer* _bagSlots_
    
    * GetNumBagUsedSlots(*[Bag|#Bag]* _bagId_)
    ** _Returns:_ *integer* _usedSlots_
    
    * GetNumBagFreeSlots(*[Bag|#Bag]* _bagId_)
    ** _Returns:_ *integer* _freeSlots_
    

    It seems to me that it duplicates an existing function, any way that I interpret it.

    My guess is that the functionality is identical for GetBagSize() and GetBagUsableSize() for any bag that isn't BAG_SUBSCRIBER_BANK. Where the difference comes in is for non-subscribers, I'd imagine. The bag size will be the same as the normal bank capacity, but it will be unusable.

    As for the other two, GetBagSize(bagId) = GetNumBagUsedSlots(bagId) + GetNumBagFreeSlots(bagId).
    Edited by silvereyes on April 25, 2017 3:21PM
  • Sounomi
    Sounomi
    ✭✭✭
    The new function "GetItemLinkGrantedRecipeIndices" doesn't seem to be working. I give it an item link for a food item I crafted and it gives me "nil" for both return values.

    I submitted a bug report in game for it but I'm posting it here too in case that doesn't go through since there isn't a category option for the API.
  • Enodoc
    Enodoc
    ✭✭✭✭✭
    ✭✭✭✭✭
    What are the full details of the updated CENTER_SCREEN_ANNOUNCE? In other words, if I currently have
    CENTER_SCREEN_ANNOUNCE:AddMessage(0, category, sound, message, message2, nil, nil, nil, nil, delay_ms, nil)
    
    what do I need instead?

    Thanks!
    Edited by Enodoc on May 17, 2017 5:20PM
    UESP: The Unofficial Elder Scrolls Pages - A collaborative source for all knowledge on the Elder Scrolls series since 1995
    Join us on Discord - discord.gg/uesp
  • Kulaan_Doskad_Hadroz
    @ZOS_GinaBruno
    Do you know what the new campaign ids are? As of 100018, they were

    CAMPAIGNS =
    {
    [3] = "Haderus",
    [12] = "Azura",
    [13] = "Blackwater",
    [23] = "Trueflame",
    }
    Though war may tear us apart, love for each other will bring us back together as an overwhelming force. ~Kulaan Doskad-Hadroz, Loredas , the 12th of Evening Star, 2E 582
  • Enodoc
    Enodoc
    ✭✭✭✭✭
    ✭✭✭✭✭
    @Kulaan_Doskad_Hadroz It should be
    [79] = "Almalexia"
    [80] = "Sotha Sil"
    [81] = "Vivec"
    [82] = "Kyne"
    [83] = "Shor"

    But you'll probably want to check that in-game with GetNumSelectionCampaigns(), GetSelectionCampaignId(campaignIndex), and GetCampaignName(campaignId).

    There's also GetCurrentCampaignId(), GetAssignedCampaignId(), and GetGuestCampaignId() for verification.
    UESP: The Unofficial Elder Scrolls Pages - A collaborative source for all knowledge on the Elder Scrolls series since 1995
    Join us on Discord - discord.gg/uesp
  • Kulaan_Doskad_Hadroz
    Thanks so much Enodoc. I'll check that out. I didn't realize those methods existed.
    Though war may tear us apart, love for each other will bring us back together as an overwhelming force. ~Kulaan Doskad-Hadroz, Loredas , the 12th of Evening Star, 2E 582
  • Kulaan_Doskad_Hadroz
    Enodoc wrote: »
    What are the full details of the updated CENTER_SCREEN_ANNOUNCE? In other words, if I currently have
    CENTER_SCREEN_ANNOUNCE:AddMessage(0, category, sound, message, message2, nil, nil, nil, nil, delay_ms, nil)
    
    what do I need instead?

    Thanks!

    So I was looking through the API (http://esoapi.uesp.net/100019/src/ingame/centerscreenannounce/centerscreenannounce.lua.html#145) and noticed that on the AddMessage method, there's a comment that basically says the method is old. "Added legacy support for addons". Makes me wonder what they replaced it with. I tried doing AddMessageWithParams, but that only gave me an error inside the game files.

    I did notice that AddMessage already calls AddMessageWithParams. In there it converts the parameters to new parameters, which makes me wonder why then AddMessage doesn't work. I dug a little deeper and noticed the few NIL checks
    if not messageParams then
                return
    

    and
    if category == CSA_CATEGORY_NO_TEXT and barParams == nil then
                    return
    


    Basically, maybe the messageParams aren't being set correctly when the AddMessage method converts the old params to new ones. That's my thought, but I'll keep digging and will let you know if I find anything.

    There must be something we're missing.
    Though war may tear us apart, love for each other will bring us back together as an overwhelming force. ~Kulaan Doskad-Hadroz, Loredas , the 12th of Evening Star, 2E 582
  • Enodoc
    Enodoc
    ✭✭✭✭✭
    ✭✭✭✭✭
    Ah, interesting, thanks! I had a reply from Harven over at ESOUI too. You may be interested in having a read: http://www.esoui.com/forums/showpost.php?p=31039&postcount=4
    UESP: The Unofficial Elder Scrolls Pages - A collaborative source for all knowledge on the Elder Scrolls series since 1995
    Join us on Discord - discord.gg/uesp
  • Kulaan_Doskad_Hadroz
    Yeah that totally helped! The only real problem that wouldn't let us use the original method was that the text style bit was changed. However, its probably good to do it with params since they probably won't keep the old way forever.
    Though war may tear us apart, love for each other will bring us back together as an overwhelming force. ~Kulaan Doskad-Hadroz, Loredas , the 12th of Evening Star, 2E 582
  • Merlin13KAGL
    Merlin13KAGL
    ✭✭✭✭✭
    ✭✭✭✭
    ESO UI API Patch Highlights (V100019)
      Subscriber Bank
      A new bank bag has been added to the game for ESO Plus subscribers and is named BAG_SUBSCRIBER_BANK. The size of the bag is the same as BAG_BACKPACK. We have also added a new bag function, GetBagUseableSize(bagId), to return how many usable slots a bag has. This will return 0 for the subscriber bank if the player does not have ESO Plus. This new bag also necessitated some changes in the lua inventory objects to support multiple bags appearing in a single inventory view. Look out for functions that once took inventoryType now taking bagId as an additional parameter.
      Hey @ZOS_GinaBruno Pretty sure this is supposed to read BAG_BANK, since it doubles bank size. ;)

      Edited by Merlin13KAGL on May 25, 2017 5:09PM
      Just because you don't like the way something is doesn't necessarily make it wrong...

      Earn it.

      IRL'ing for a while for assorted reasons, in forum, and in game.
      I am neither warm, nor fuzzy...
      Probably has checkbox on Customer Service profile that say High Aggro, 99% immunity to BS
    Sign In or Register to comment.