diff --git a/ESOUIDocumentation.txt b/ESOUIDocumentation.txt index 7484f9c14..d6d03bf01 100644 --- a/ESOUIDocumentation.txt +++ b/ESOUIDocumentation.txt @@ -1,5 +1,5 @@ {TOC:maxLevel=3} -h1. ESO UI Documentation for API Version 101037 +h1. ESO UI Documentation for API Version 101038 h2. VM Functions * ScriptBuildInfo() ** _Returns:_ *table* _buildInfo_ @@ -56,6 +56,7 @@ h5. Alliance h5. ApprovedURLType * APPROVED_URL_ESO_ACCOUNT +* APPROVED_URL_ESO_ACCOUNT_LINKING * APPROVED_URL_ESO_ACCOUNT_STORE * APPROVED_URL_ESO_ACCOUNT_SUBSCRIPTION * APPROVED_URL_ESO_FORUMS @@ -725,18 +726,18 @@ h5. PendingFeedbackType h5. PlatformAccountLabel -* ACCOUNT_LABEL_HERON * ACCOUNT_LABEL_PC * ACCOUNT_LABEL_PS4 * ACCOUNT_LABEL_PS5 +* ACCOUNT_LABEL_REUSE_ME * ACCOUNT_LABEL_XBOX h5. PlatformStoreLabel * PLATFORM_STORE_LABEL_DMM * PLATFORM_STORE_LABEL_EPIC -* PLATFORM_STORE_LABEL_HERON * PLATFORM_STORE_LABEL_PSN +* PLATFORM_STORE_LABEL_REUSE_ME * PLATFORM_STORE_LABEL_STEAM * PLATFORM_STORE_LABEL_XBL * PLATFORM_STORE_LABEL_ZOS @@ -838,6 +839,13 @@ h5. RaidPointReason * RAID_POINT_REASON_SOLO_ARENA_PICKUP_TWO +h5. RandomRollResult +* RANDOM_ROLL_RESULT_FAILED +* RANDOM_ROLL_RESULT_INVALID_NUM_ROLLS +* RANDOM_ROLL_RESULT_INVALID_RESULT +* RANDOM_ROLL_RESULT_SUCCESS + + h5. RatingsBoard * RATINGS_BOARD_BR * RATINGS_BOARD_ESRB @@ -1209,7 +1217,9 @@ h5. TutorialTrigger * TUTORIAL_TRIGGER_EQUIPMENT_OUT_OF_CHARGES * TUTORIAL_TRIGGER_EQUIPPED_ANY_ARMOR * TUTORIAL_TRIGGER_EQUIPPED_ANY_WEAPON +* TUTORIAL_TRIGGER_EVENT_TICKET_DROP_ON_COOLDOWN * TUTORIAL_TRIGGER_FENCE_OPENED +* TUTORIAL_TRIGGER_FILLETING_OPENED * TUTORIAL_TRIGGER_FUGITIVE_REACHED * TUTORIAL_TRIGGER_GAINED_BIND_ON_EQUIP_ITEM * TUTORIAL_TRIGGER_GAINED_CRAFTING_MATERIAL @@ -1238,7 +1248,6 @@ h5. TutorialTrigger * TUTORIAL_TRIGGER_GUILD_CHAT * TUTORIAL_TRIGGER_HELP_CUSTOMER_SUPPORT_OPENED * TUTORIAL_TRIGGER_HELP_TUTORIALS_OPENED -* TUTORIAL_TRIGGER_HERON_THIRD_PARTY_CONTROLLER_SHOWING * TUTORIAL_TRIGGER_HOME_STORAGE_OPENED * TUTORIAL_TRIGGER_HOUSING_EDITOR_ENTERED_LINK_MODE * TUTORIAL_TRIGGER_HOUSING_EDITOR_ENTERED_PATH_MODE @@ -1247,7 +1256,7 @@ h5. TutorialTrigger * TUTORIAL_TRIGGER_INCOMING_PLAYER_TO_PLAYER_NOTIFICATION * TUTORIAL_TRIGGER_INVENTORY_FULL * TUTORIAL_TRIGGER_INVENTORY_OPENED -* TUTORIAL_TRIGGER_INVENTORY_OPENED_AND_POISONS_PRESENT +* TUTORIAL_TRIGGER_INVENTORY_OPENED_AND_FISH_PRESENT * TUTORIAL_TRIGGER_INVENTORY_OPENED_AND_QUICKSLOTS_AVAILABLE * TUTORIAL_TRIGGER_INVENTORY_OPENED_AND_STOLEN_ITEMS_PRESENT * TUTORIAL_TRIGGER_INVENTORY_OPENED_AND_WEAPON_SETS_AVAILABLE @@ -1301,7 +1310,7 @@ h5. TutorialTrigger * TUTORIAL_TRIGGER_RECEIVED_WHISPER * TUTORIAL_TRIGGER_REFUGE_ENTERED * TUTORIAL_TRIGGER_RETRAIT_STATION_OPENED -* TUTORIAL_TRIGGER_REUSE_ME1 +* TUTORIAL_TRIGGER_REUSE_ME * TUTORIAL_TRIGGER_RIDING_SKILL_MANAGEMENT_OPENED * TUTORIAL_TRIGGER_SCALEABLE_REGION_ENTERED * TUTORIAL_TRIGGER_SEAL_MARKET_OPENED @@ -1323,9 +1332,11 @@ h5. TutorialTrigger * TUTORIAL_TRIGGER_TRIBUTE_CARD_UPGRADED * TUTORIAL_TRIGGER_TRIBUTE_CHOICE_CARD_SEEN * TUTORIAL_TRIGGER_TRIBUTE_CLUE_ACQUIRED +* TUTORIAL_TRIGGER_TRIBUTE_CONFINE_CARD_SEEN * TUTORIAL_TRIGGER_TRIBUTE_CONTRACT_AGENT_CARD_SEEN * TUTORIAL_TRIGGER_TRIBUTE_CONTRACT_CARD_SEEN * TUTORIAL_TRIGGER_TRIBUTE_CURSE_CARD_SEEN +* TUTORIAL_TRIGGER_TRIBUTE_DONATE_CARD_SEEN * TUTORIAL_TRIGGER_TRIBUTE_FINDER_OPENED * TUTORIAL_TRIGGER_TRIBUTE_LOSE_PRESTIGE * TUTORIAL_TRIGGER_TRIBUTE_PVP_VICTORY @@ -1369,10 +1380,10 @@ h5. UIMonsterDifficulty h5. UIPlatform -* UI_PLATFORM_HERON * UI_PLATFORM_PC * UI_PLATFORM_PS4 * UI_PLATFORM_PS5 +* UI_PLATFORM_REUSE_ME * UI_PLATFORM_XBOX @@ -1508,6 +1519,9 @@ h5. Globals * NUM_LOCKPICK_CHAMBERS * TRADE_NUM_SLOTS * MAX_PASSWORD_LENGTH +* RANDOM_ROLL_MAX_NUM_ROLLS +* RANDOM_ROLL_MAX_RESULT +* RANDOM_ROLL_MIN_RESULT * TRADE_DELAY_TIME * TUTORIAL_ENABLED_SETTING_ID * VOICE_CHAT_OFFICERS_ROOM_NUMBER @@ -1565,6 +1579,7 @@ h5. AbilityType * ABILITY_TYPE_HARDDISMOUNT * ABILITY_TYPE_HEAL * ABILITY_TYPE_HIDE +* ABILITY_TYPE_HOTBARSLOTOVERRIDE * ABILITY_TYPE_IMMUNITY * ABILITY_TYPE_INTERACTREFUSALOVERRIDE * ABILITY_TYPE_INTERCEPT @@ -2645,6 +2660,7 @@ h5. Chapter * CHAPTER_BASE_GAME * CHAPTER_DUNE * CHAPTER_GLACIER +* CHAPTER_MAGMA * CHAPTER_MESA * CHAPTER_SCARP * CHAPTER_VOLCANO @@ -2767,6 +2783,10 @@ h5. CollectibleUsageBlockReason * COLLECTIBLE_USAGE_BLOCK_REASON_WORLD_EVENT +h5. CollectibleUserFlags +* COLLECTIBLE_USER_FLAG_FAVORITE + + h5. PlayerFxOverrideAbilityType * PLAYER_FX_OVERRIDE_ABILITY_TYPE_WAYSHRINE @@ -3661,53 +3681,38 @@ h5. GuildEventType * GUILD_EVENT_ABOUT_US_EDITED * GUILD_EVENT_ADDED_TO_BLACKLIST * GUILD_EVENT_BANKGOLD_ADDED -* GUILD_EVENT_BANKGOLD_GUILD_STORE_TAX * GUILD_EVENT_BANKGOLD_KIOSK_BID * GUILD_EVENT_BANKGOLD_KIOSK_BID_REFUND -* GUILD_EVENT_BANKGOLD_PURCHASE_HERALDRY * GUILD_EVENT_BANKGOLD_REMOVED * GUILD_EVENT_BANKITEM_ADDED * GUILD_EVENT_BANKITEM_REMOVED -* GUILD_EVENT_DEPRECATED_1 -* GUILD_EVENT_DEPRECATED_2 -* GUILD_EVENT_DEPRECATED_3 -* GUILD_EVENT_DEPRECATED_4 * GUILD_EVENT_EDIT_BLACKLIST_NOTE * GUILD_EVENT_GUILD_APPLICATION_ACCEPTED * GUILD_EVENT_GUILD_APPLICATION_DECLINED * GUILD_EVENT_GUILD_BANK_LOCKED * GUILD_EVENT_GUILD_BANK_UNLOCKED * GUILD_EVENT_GUILD_CREATE -* GUILD_EVENT_GUILD_DELETE * GUILD_EVENT_GUILD_DEMOTE * GUILD_EVENT_GUILD_INVITE -* GUILD_EVENT_GUILD_INVITEDECLINED -* GUILD_EVENT_GUILD_INVITEPURGED -* GUILD_EVENT_GUILD_INVITEREVOKED * GUILD_EVENT_GUILD_JOIN * GUILD_EVENT_GUILD_KICKED * GUILD_EVENT_GUILD_KIOSK_LOCKED * GUILD_EVENT_GUILD_KIOSK_PURCHASED -* GUILD_EVENT_GUILD_KIOSK_PURCHASE_REFUND * GUILD_EVENT_GUILD_KIOSK_UNLOCKED * GUILD_EVENT_GUILD_LEAVE * GUILD_EVENT_GUILD_PROMOTE * GUILD_EVENT_GUILD_RECRUITMENT_GUILD_LISTED * GUILD_EVENT_GUILD_RECRUITMENT_GUILD_UNLISTED -* GUILD_EVENT_GUILD_REMOVE * GUILD_EVENT_GUILD_STORE_LOCKED * GUILD_EVENT_GUILD_STORE_UNLOCKED * GUILD_EVENT_GUILD_TABARD_LOCKED * GUILD_EVENT_GUILD_TABARD_UNLOCKED -* GUILD_EVENT_GUILD_UNINVITE * GUILD_EVENT_HERALDRY_EDITED -* GUILD_EVENT_ITEM_LISTED * GUILD_EVENT_ITEM_SOLD * GUILD_EVENT_KEEP_CLAIMED * GUILD_EVENT_KEEP_LOST * GUILD_EVENT_KEEP_RELEASED * GUILD_EVENT_MOTD_EDITED -* GUILD_EVENT_NAME_CHANGED * GUILD_EVENT_REMOVED_FROM_BLACKLIST @@ -4610,6 +4615,7 @@ h5. CollectibleItemType h5. DeconstructActionName * DECONSTRUCT_ACTION_NAME_DECONSTRUCT * DECONSTRUCT_ACTION_NAME_EXTRACT +* DECONSTRUCT_ACTION_NAME_FILLET * DECONSTRUCT_ACTION_NAME_REFINE @@ -5168,6 +5174,7 @@ h5. ItemUseType * ITEM_USE_TYPE_COLLECTIBLE_GRANT * ITEM_USE_TYPE_COMBINATION * ITEM_USE_TYPE_COSTUME_DYE_STAMP +* ITEM_USE_TYPE_FILLET_FISH * ITEM_USE_TYPE_ITEM_DYE_STAMP * ITEM_USE_TYPE_KEEP_RECALL_STONE * ITEM_USE_TYPE_MORPH_RESPEC @@ -5497,6 +5504,7 @@ h5. WeaponConfigType * WEAPON_CONFIG_TYPE_ONE_HANDED * WEAPON_CONFIG_TYPE_ONE_HAND_AND_SHIELD * WEAPON_CONFIG_TYPE_RESTO_STAFF +* WEAPON_CONFIG_TYPE_SHIELD_ONLY * WEAPON_CONFIG_TYPE_TWO_HANDED * WEAPON_CONFIG_TYPE_UNARMED * WEAPON_CONFIG_TYPE_WEREWOLF @@ -5619,6 +5627,9 @@ h5. Globals h5. AccessibilitySetting * ACCESSIBILITY_SETTING_ACCESSIBILITY_MODE +* ACCESSIBILITY_SETTING_ACCESSIBLE_QUICKWHEELS +* ACCESSIBILITY_SETTING_GAMEPAD_AIM_ASSIST_INTENSITY +* ACCESSIBILITY_SETTING_MOUSE_AIM_ASSIST_INTENSITY * ACCESSIBILITY_SETTING_NARRATION_VOICE_SPEED * ACCESSIBILITY_SETTING_NARRATION_VOICE_TYPE * ACCESSIBILITY_SETTING_NARRATION_VOLUME @@ -5839,6 +5850,12 @@ h5. GamepadSetting * GAMEPAD_SETTING_WAS_LAST_INPUT_GAMEPAD +h5. GuildKeepNoticesSettingChoice +* GUILD_KEEP_NOTICES_SETTING_CHOICE_ALERT +* GUILD_KEEP_NOTICES_SETTING_CHOICE_CHAT +* GUILD_KEEP_NOTICES_SETTING_CHOICE_DONT_SHOW + + h5. InWorldUISetting * IN_WORLD_UI_SETTING_COMPANION_PASSENGER_PREFERENCE * IN_WORLD_UI_SETTING_COMPANION_REACTION_FREQUENCY @@ -6028,6 +6045,12 @@ h5. RaidLifeVisibilityChoice * RAID_LIFE_VISIBILITY_CHOICE_ON +h5. RandomMountType +* RANDOM_MOUNT_TYPE_ANY +* RANDOM_MOUNT_TYPE_FAVORITE +* RANDOM_MOUNT_TYPE_NONE + + h5. RealmSelectMethod * REALM_SELECT_METHOD_DEFAULT_REALM * REALM_SELECT_METHOD_LAST_REALM @@ -6131,6 +6154,7 @@ h5. TextureResolutionChoice h5. UISetting * UI_SETTING_ALWAYS_SHOW_STATUS_TEXT +* UI_SETTING_AUTOMATIC_QUEST_TRACKING * UI_SETTING_AUTO_DECLINE_DUEL_INVITES * UI_SETTING_AUTO_DECLINE_TRIBUTE_INVITES * UI_SETTING_COMPASS_ACTIVE_QUESTS @@ -6160,6 +6184,7 @@ h5. UISetting * UI_SETTING_SHOW_ARMOR_INDICATOR * UI_SETTING_SHOW_AVA_NOTIFICATIONS * UI_SETTING_SHOW_FRAMERATE +* UI_SETTING_SHOW_GUILD_KEEP_NOTICES * UI_SETTING_SHOW_HOUSE_TRACKER * UI_SETTING_SHOW_LATENCY * UI_SETTING_SHOW_LEADERBOARD_NOTIFICATIONS @@ -7070,6 +7095,7 @@ h5. StoreFailure * STORE_FAILURE_ALREADY_UNEARTHED_ANTIQUITY * STORE_FAILURE_AT_FENCE_LIMIT * STORE_FAILURE_AWARDS_ALREADY_OWNED_COLLECTIBLE +* STORE_FAILURE_AWARDS_FRAGMENT_OF_ALREADY_OWNED_COLLECTIBLE * STORE_FAILURE_BUY_ITEM_FAILED_REQS * STORE_FAILURE_CANT_BE_SOLD * STORE_FAILURE_CANT_BUY_MULTIPLES @@ -7124,7 +7150,6 @@ h5. MarketingPreferencesRequestResult h5. PlatformServiceType * PLATFORM_SERVICE_TYPE_DMM * PLATFORM_SERVICE_TYPE_EPIC -* PLATFORM_SERVICE_TYPE_HERON * PLATFORM_SERVICE_TYPE_PSN * PLATFORM_SERVICE_TYPE_STEAM * PLATFORM_SERVICE_TYPE_XBL @@ -7136,7 +7161,6 @@ h5. PlayerPlatformType * PLAYER_PLATFORM_EPIC * PLAYER_PLATFORM_PC * PLAYER_PLATFORM_PLAYSTATION -* PLAYER_PLATFORM_STADIA * PLAYER_PLATFORM_STEAM * PLAYER_PLATFORM_XBOX @@ -7261,9 +7285,10 @@ h5. GroupVoteChoice h5. Globals -* GROUP_SIZE_MAX -* RAID_GROUP_SIZE_THRESHOLD +* LARGE_GROUP_SIZE_THRESHOLD +* MAX_GROUP_SIZE_THRESHOLD * SMALL_GROUP_SIZE_THRESHOLD +* STANDARD_GROUP_SIZE_THRESHOLD h5. Globals @@ -7756,6 +7781,7 @@ h5. TributeBoardLocation * TRIBUTE_BOARD_LOCATION_OPPONENT_DECK_INTRO * TRIBUTE_BOARD_LOCATION_OPPONENT_HAND * TRIBUTE_BOARD_LOCATION_OPPONENT_PERM_REMOVED +* TRIBUTE_BOARD_LOCATION_OPPONENT_PRISON * TRIBUTE_BOARD_LOCATION_PLAYER_BOARD_ACTION * TRIBUTE_BOARD_LOCATION_PLAYER_BOARD_AGENT * TRIBUTE_BOARD_LOCATION_PLAYER_COOLDOWN @@ -7763,6 +7789,7 @@ h5. TributeBoardLocation * TRIBUTE_BOARD_LOCATION_PLAYER_DECK_INTRO * TRIBUTE_BOARD_LOCATION_PLAYER_HAND * TRIBUTE_BOARD_LOCATION_PLAYER_PERM_REMOVED +* TRIBUTE_BOARD_LOCATION_PLAYER_PRISON h5. TributeCardPile @@ -7958,10 +7985,12 @@ h5. TributeMechanic * TRIBUTE_MECHANIC_ACQUIRE_CARDS * TRIBUTE_MECHANIC_AGENT_SELF_HEAL * TRIBUTE_MECHANIC_BONUS_PATRON_INTERACTION +* TRIBUTE_MECHANIC_CONFINE_CARDS * TRIBUTE_MECHANIC_CREATE_CARDS * TRIBUTE_MECHANIC_CULL_FROM_DOCKS * TRIBUTE_MECHANIC_DESTROY_CARDS * TRIBUTE_MECHANIC_DISCARD_CARDS +* TRIBUTE_MECHANIC_DONATE_CARDS * TRIBUTE_MECHANIC_DRAW_CARDS * TRIBUTE_MECHANIC_GAIN_RESOURCES * TRIBUTE_MECHANIC_HEAL_AGENT @@ -8011,6 +8040,7 @@ h5. TributePatronPerspectiveFavorState h5. TributePatronRequirement +* TRIBUTE_PATRON_REQUIREMENT_DISCARD_CARD * TRIBUTE_PATRON_REQUIREMENT_HAS_CARD * TRIBUTE_PATRON_REQUIREMENT_PAY_RESOURCE * TRIBUTE_PATRON_REQUIREMENT_SACRIFICE_CARD @@ -8054,6 +8084,7 @@ h5. TributeResource h5. TributeTargetSelectionConfirmationResult +* TRIBUTE_TARGET_SELECTION_CONFIRMATION_RESULT_MAX_CONFINE_TARGETS_REACHED * TRIBUTE_TARGET_SELECTION_CONFIRMATION_RESULT_NOT_ENOUGH_TARGETS * TRIBUTE_TARGET_SELECTION_CONFIRMATION_RESULT_REQUIRES_TAUNT_AGENTS * TRIBUTE_TARGET_SELECTION_CONFIRMATION_RESULT_SUCCESS @@ -8086,6 +8117,7 @@ h5. TributeVictoryType h5. Globals +* TRIBUTE_DEFAULT_PATRON_USAGE_COUNT * TRIBUTE_CHAPTER_ZONE_ID * TRIBUTE_PATRON_SELECTION_DELAY_SECONDS @@ -8724,6 +8756,7 @@ h5. ProspectiveAlchemyResult h5. ProvisionerSpecialIngredientType +* PROVISIONER_SPECIAL_INGREDIENT_TYPE_FILLET * PROVISIONER_SPECIAL_INGREDIENT_TYPE_FLAVORING * PROVISIONER_SPECIAL_INGREDIENT_TYPE_FURNISHING * PROVISIONER_SPECIAL_INGREDIENT_TYPE_NONE @@ -9388,11 +9421,6 @@ h5. MouseCursorType * MOUSE_CURSOR_ERASE * MOUSE_CURSOR_FILL * MOUSE_CURSOR_FILL_MULTIPLE -* MOUSE_CURSOR_GENERIC_HOLD_ABILITY -* MOUSE_CURSOR_GENERIC_HOLD_COLLECTIBLE -* MOUSE_CURSOR_GENERIC_HOLD_EMOTE -* MOUSE_CURSOR_GENERIC_HOLD_ITEM -* MOUSE_CURSOR_GENERIC_HOLD_QUEST_ITEM * MOUSE_CURSOR_ICON * MOUSE_CURSOR_NEXT_LEFT * MOUSE_CURSOR_NEXT_RIGHT @@ -9534,11 +9562,11 @@ h5. Globals h5. GamepadType -* GAMEPAD_TYPE_HERON * GAMEPAD_TYPE_NONE * GAMEPAD_TYPE_PS4 * GAMEPAD_TYPE_PS4_NO_TOUCHPAD * GAMEPAD_TYPE_PS5 +* GAMEPAD_TYPE_STADIA * GAMEPAD_TYPE_SWITCH * GAMEPAD_TYPE_XBOX * GAMEPAD_TYPE_XBSX @@ -9817,7 +9845,6 @@ h5. GraphicsMode h5. GraphicsPresets * GRAPHICS_PRESETS_CUSTOM -* GRAPHICS_PRESETS_HERON * GRAPHICS_PRESETS_HIGH * GRAPHICS_PRESETS_LOW * GRAPHICS_PRESETS_MAXIMUM @@ -9827,6 +9854,7 @@ h5. GraphicsPresets * GRAPHICS_PRESETS_PS4PLUS1080P * GRAPHICS_PRESETS_PS4PLUS4K * GRAPHICS_PRESETS_PS5 +* GRAPHICS_PRESETS_REUSE_ME * GRAPHICS_PRESETS_SCORPIO * GRAPHICS_PRESETS_ULTRA * GRAPHICS_PRESETS_XB1 @@ -9856,6 +9884,8 @@ h5. SubSamplingMode h5. Globals h2. Game API +* ReloadUI(*string* _guiName_) + * GetCVar(*string* _CVarName_) ** _Returns:_ *string* _value_ @@ -9978,20 +10008,32 @@ h2. Game API * CompareId64s(*id64* _firstId_, *id64* _secondId_) ** _Returns:_ *integer* _result_ -* CompareId64ToNumber(*id64* _id_, *integer* _number_) +* CompareId64ToNumber(*id64* _id_, *integer53* _number_) ** _Returns:_ *integer* _result_ -* BitAnd(*integer* _valueA_, *integer* _valueB_) -** _Returns:_ *integer* _result_ +* Id64ToNumber(*id64* _id_) +** _Returns:_ *integer53* _number_, *bool* _lostPrecisionUseId64ToString_ -* BitOr(*integer* _valueA_, *integer* _valueB_) -** _Returns:_ *integer* _result_ +* NumberToId64(*integer53* _number_) +** _Returns:_ *id64* _id_, *bool* _lostPrecisionUseStringToId64_ -* BitLShift(*integer* _value_, *integer* _numBits_) -** _Returns:_ *integer* _result_ +* BitAnd(*integer53* _valueA_, *integer53* _valueB_) +** _Returns:_ *integer53* _result_ -* BitRShift(*integer* _value_, *integer* _numBits_) -** _Returns:_ *integer* _result_ +* BitOr(*integer53* _valueA_, *integer53* _valueB_) +** _Returns:_ *integer53* _result_ + +* BitXor(*integer53* _valueA_, *integer53* _valueB_) +** _Returns:_ *integer53* _result_ + +* BitNot(*integer53* _value_, *integer* _numBits_) +** _Returns:_ *integer53* _result_ + +* BitLShift(*integer53* _value_, *integer* _numBits_) +** _Returns:_ *integer53* _result_ + +* BitRShift(*integer53* _value_, *integer* _numBits_) +** _Returns:_ *integer53* _result_ * HideMouse(*bool* _onlyConsiderWhileMoving_) @@ -10005,9 +10047,6 @@ h2. Game API * GetFrameTimeSeconds() ** _Returns:_ *number* _frameTimeInSeconds_ -* GetTimeStamp32() -** _Returns:_ *integer* _timestamp_ - * GetFrameDeltaTimeSeconds() ** _Returns:_ *number* _frameDeltaTimeInSeconds_ @@ -10032,7 +10071,7 @@ h2. Game API * GetFramerate() ** _Returns:_ *number* _currentFramerate_ -* GetDiffBetweenTimeStamps(*deprecated_timestamp_64* _laterTime_, *deprecated_timestamp_64* _earlierTime_) +* GetDiffBetweenTimeStamps(*integer53* _laterTime_, *integer53* _earlierTime_) ** _Returns:_ *number* _difference_ * FormatTimeSeconds(*number* _timeValueInSeconds_, *[TimeFormatStyleCode|#TimeFormatStyleCode]* _formatType_, *[TimeFormatPrecisionCode|#TimeFormatPrecisionCode]* _precisionType_, *[TimeFormatDirectionCode|#TimeFormatDirectionCode]* _direction_) @@ -10127,6 +10166,9 @@ h2. Game API * IsSystemUsingHDR() ** _Returns:_ *bool* _usesHDR_ +* ShouldShowAdvancedUIErrors() +** _Returns:_ *bool* _shouldShowAdvancedUIErrors_ + * TakeScreenshot() * GetESOFullVersionString() @@ -10234,7 +10276,10 @@ h2. Game API ** _Returns:_ *integer* _frameTimeInMilliseconds_ * GetTimeStamp() -** _Returns:_ *deprecated_timestamp_64* _timestamp_ +** _Returns:_ *integer53* _timestamp_ + +* GetTimeStamp32() +** _Returns:_ *integer* _timestamp_ * GetDate() ** _Returns:_ *integer* _currentTime_ @@ -10242,16 +10287,16 @@ h2. Game API * GetTimeString() ** _Returns:_ *string* _currentTimeString_ -* GetDateElementsFromTimestamp(*deprecated_timestamp_64* _timestamp_) +* GetDateElementsFromTimestamp(*integer53* _timestamp_) ** _Returns:_ *integer* _year_, *integer* _month_, *integer* _day_ * GetTimestampForStartOfDate(*integer* _year_, *integer* _month_, *integer* _day_, *bool* _inLocalTime_) -** _Returns:_ *deprecated_timestamp_64* _timestamp_ +** _Returns:_ *integer53* _timestamp_ * GetFormattedTime() ** _Returns:_ *integer* _formattedTime_ -* GetDayOfTheWeekIndex(*deprecated_timestamp_64* _timestamp_) +* GetDayOfTheWeekIndex(*integer53* _timestamp_) ** _Returns:_ *integer* _weekdayIndex_ * GetNumDaysInMonth(*integer* _year_, *integer* _month_) @@ -10281,9 +10326,6 @@ h2. Game API * GetFriendCharacterInfo(*luaindex* _friendIndex_) ** _Returns:_ *bool* _hasCharacter_, *string* _characterName_, *string* _zoneName_, *integer* _classType_, *[Alliance|#Alliance]* _alliance_, *integer* _level_, *integer* _championRank_, *integer* _zoneId_, *id64* _consoleId_ -* GetFriendHeronName(*luaindex* _friendIndex_) -** _Returns:_ *string:nilable* _heronName_ - * GetNumIgnored() ** _Returns:_ *integer* _numIgnored_ @@ -10444,6 +10486,9 @@ h2. Game API * GetGuildRankId(*integer* _guildId_, *luaindex* _rankIndex_) ** _Returns:_ *integer* _rankId_ +* GetGuildRankIndex(*integer* _guildId_, *integer* _rankId_) +** _Returns:_ *luaindex:nilable* _rankIndex_ + * IsGuildRankGuildMaster(*integer* _guildId_, *luaindex* _rankIndex_) ** _Returns:_ *bool* _isGuildMaster_ @@ -10686,9 +10731,6 @@ h2. Game API * IsConsoleUI() ** _Returns:_ *bool* _isConsoleUI_ -* IsHeronUI() -** _Returns:_ *bool* _isHeronUI_ - * IsMacUI() ** _Returns:_ *bool* _isMacUI_ @@ -11014,6 +11056,8 @@ h2. Game API * ClearAllNarrationQueues() +* ClearActiveNarration() + * SetTextChatNarrationQueueEnabled(*bool* _enabled_) * SetCenterScreenAnnounceNarrationQueueEnabled(*bool* _enabled_) @@ -11021,8 +11065,6 @@ h2. Game API * ToggleShowIngameGui() -* ReloadUI(*string* _guiName_) - * GetNumPlayerStatuses() ** _Returns:_ *integer* _numStatuses_ @@ -12033,6 +12075,9 @@ h2. Game API * GetActionLayerNameByIndex(*luaindex* _layerIndex_) ** _Returns:_ *string* _layerName_ +* IsActionLayerTopLayerByName(*string* _layerName_) +** _Returns:_ *bool* _isTopLayer_ + * GetNumCharacters() ** _Returns:_ *integer* _numCharacters_ @@ -12467,6 +12512,12 @@ h2. Game API * IsActionSlotLocked(*luaindex* _actionSlotIndex_, *[HotBarCategory|#HotBarCategory]:nilable* _hotbarCategory_) ** _Returns:_ *bool* _isLocked_ +* IsActionSlotMutable(*luaindex* _actionSlotIndex_, *[HotBarCategory|#HotBarCategory]:nilable* _hotbarCategory_) +** _Returns:_ *bool* _isMutable_ + +* ActionSlotHasEffectiveSlotAbilityData(*luaindex* _actionSlotIndex_, *[HotBarCategory|#HotBarCategory]:nilable* _hotbarCategory_) +** _Returns:_ *bool* _hasEffectiveSlotAbilityData_ + * GetActionSlotUnlockText(*luaindex* _actionSlotIndex_, *[HotBarCategory|#HotBarCategory]* _hotbarCategory_) ** _Returns:_ *string* _slotUnlockText_ @@ -12798,6 +12849,12 @@ h2. Game API * IsChatSystemAvailableForCurrentPlatform() ** _Returns:_ *bool* _enabled_ +* RandomDiceRoll *private* (*integer* _maxValue_, *integer* _numRolls_, *integer* _modifier_) +** _Returns:_ *[RandomRollResult|#RandomRollResult]* _result_ + +* RandomRangeRoll *private* (*integer* _minValue_, *integer* _maxValue_) +** _Returns:_ *[RandomRollResult|#RandomRollResult]* _result_ + * SetSessionIgnore(*string* _userName_, *bool* _isIgnoredThisSession_) * ClearSessionIgnores() @@ -13322,6 +13379,9 @@ h2. Game API * GetCollectibleIdForZone(*luaindex* _zoneIndex_) ** _Returns:_ *integer* _collectibleId_ +* IsZoneCollectibleLocked(*luaindex* _zoneIndex_) +** _Returns:_ *bool* _isZoneCollectibleLocked_ + * GetZoneIndex(*integer* _zoneId_) ** _Returns:_ *luaindex* _zoneIndex_ @@ -14651,7 +14711,7 @@ h2. Game API ** _Returns:_ *id64* _progress_ * GetAchievementTimestamp(*integer* _achievementId_) -** _Returns:_ *id64* _timestamp_ +** _Returns:_ *integer53* _timestamp_ * GetAchievementInfo(*integer* _achievementId_) ** _Returns:_ *string* _name_, *string* _description_, *integer* _points_, *textureName* _icon_, *bool* _completed_, *string* _date_, *string* _time_ @@ -17365,6 +17425,11 @@ h2. Game API * GetNumCollectiblesInCollectibleCategory(*luaindex* _topLevelIndex_, *luaindex:nilable* _subCategoryIndex_) ** _Returns:_ *integer* _numCollectibles_ +* SetRandomMountType(*[RandomMountType|#RandomMountType]* _randomMountType_, *[GameplayActorCategory|#GameplayActorCategory]* _actorCategory_) + +* GetRandomMountType(*[GameplayActorCategory|#GameplayActorCategory]* _actorCategory_) +** _Returns:_ *[RandomMountType|#RandomMountType]* _randomMountType_ + * HasActiveCompanion() ** _Returns:_ *bool* _hasActiveCompanion_ @@ -17602,6 +17667,9 @@ h2. Game API * Disconnect *private* () +* HasClaimedAccountReward(*integer* _rewardDefId_) +** _Returns:_ *bool* _hasClaimedAccountReward_ + * SetFullscreenEffect(*[FullscreenEffectType|#FullscreenEffectType]* _effectType_, *number* _param1_, *number* _param2_, *bool* _immediateUpdate_) * IsBankOpen() @@ -18274,6 +18342,9 @@ h2. Game API * HasPoisonInBag(*[Bag|#Bag]* _bagId_) ** _Returns:_ *bool* _hasPoison_ +* HasFishInBag(*[Bag|#Bag]* _bagId_) +** _Returns:_ *bool* _hasFish_ + * GetTelvarStoneMultiplierThresholdIndex() ** _Returns:_ *luaindex:nilable* _thresholdIndex_ @@ -18510,12 +18581,21 @@ h2. Game API * GetTotalUnlockedCollectiblesByCategoryType(*[CollectibleCategoryType|#CollectibleCategoryType]* _collectibleCategoryType_) ** _Returns:_ *integer* _count_ +* HasAnyUnlockedCollectiblesByCategoryType(*[CollectibleCategoryType|#CollectibleCategoryType]* _collectibleCategoryType_) +** _Returns:_ *bool* _hasAnyUnlocked_ + +* HasAnyUnlockedCollectiblesAvailableToActorCategoryByCategoryType(*[CollectibleCategoryType|#CollectibleCategoryType]* _collectibleCategoryType_, *[GameplayActorCategory|#GameplayActorCategory]* _actorCategory_) +** _Returns:_ *bool* _hasAnyUnlocked_ + * GetCollectibleIdFromType(*[CollectibleCategoryType|#CollectibleCategoryType]* _collectibleCategoryType_, *luaindex* _index_) ** _Returns:_ *integer* _collectibleId_ * IsCollectibleCategorySlottable(*[CollectibleCategoryType|#CollectibleCategoryType]* _collectibleCategoryType_) ** _Returns:_ *bool* _isSlottable_ +* IsCollectibleCategoryFavoritable(*[CollectibleCategoryType|#CollectibleCategoryType]* _collectibleCategoryType_) +** _Returns:_ *bool* _canBeFavorited_ + * IsCollectibleCategoryUsable(*[CollectibleCategoryType|#CollectibleCategoryType]* _collectibleCategoryType_, *[GameplayActorCategory|#GameplayActorCategory]* _actorCategory_) ** _Returns:_ *bool* _isUsable_ @@ -18585,6 +18665,9 @@ h2. Game API * GetCollectibleNickname(*integer* _collectibleId_) ** _Returns:_ *string* _name_ +* GetCollectibleDefaultNickname(*integer* _collectibleId_) +** _Returns:_ *string* _name_ + * GetCollectibleHelpIndices(*integer* _collectibleId_) ** _Returns:_ *luaindex:nilable* _helpCategoryIndex_, *luaindex:nilable* _helpIndex_ @@ -18611,12 +18694,23 @@ h2. Game API * IsCollectibleUnlocked(*integer* _collectibleId_) ** _Returns:_ *bool* _isUnlocked_ +* SetOrClearCollectibleUserFlag(*integer* _collectibleId_, *[CollectibleUserFlags|#CollectibleUserFlags]* _userFlag_, *bool* _isSet_) + +* GetCollectibleUserFlags(*integer* _collectibleId_) +** _Returns:_ *[CollectibleUserFlags|#CollectibleUserFlags]* _userFlags_ + +* DoesCollectibleCategoryContainAnyCollectiblesWithUserFlags(*[CollectibleCategoryType|#CollectibleCategoryType]* _categoryType_, *[CollectibleUserFlags|#CollectibleUserFlags]* _userFlags_) +** _Returns:_ *bool* _containsCollectible_ + * IsCollectibleActive(*integer* _collectibleId_, *[GameplayActorCategory|#GameplayActorCategory]* _actorCategory_) ** _Returns:_ *bool* _isActive_ * IsCollectibleOwnedByDefId(*integer* _collectibleId_) ** _Returns:_ *bool* _owned_ +* CanAcquireCollectibleByDefId(*integer* _collectibleId_) +** _Returns:_ *bool* _canAcquire_ + * GetImperialCityCollectibleId() ** _Returns:_ *integer* _collectibleId_ @@ -18790,6 +18884,9 @@ h2. Game API * GetMarketProductChildId *private* (*integer* _marketProductId_, *luaindex* _childIndex_) ** _Returns:_ *integer* _childId_ +* GetMarketProductItemRewardListId *private* (*integer* _marketProductId_) +** _Returns:_ *integer* _rewardListId_ + * GetMarketProductNumBundledProducts *private* (*integer* _marketProductId_) ** _Returns:_ *integer* _numBundledProducts_ @@ -19871,10 +19968,10 @@ h2. Game API * GetTributePatronRequirementIconPath(*[TributePatronRequirement|#TributePatronRequirement]* _requirementType_, *integer* _param1_, *integer* _param2_) ** _Returns:_ *string* _iconPath_ -* GetTributeMechanicTargetingText(*[TributeMechanic|#TributeMechanic]* _mechanicType_, *integer* _quantity_, *integer* _param1_, *integer* _param2_, *integer* _param3_) +* GetTributeMechanicTargetingText(*[TributeMechanic|#TributeMechanic]* _mechanicType_, *integer* _quantity_, *integer* _param1_, *integer* _param2_, *integer* _param3_, *string* _targetingFormatterOverrideText_) ** _Returns:_ *string* _targetingText_ -* GetTributePatronRequirementTargetingText(*[TributePatronRequirement|#TributePatronRequirement]* _requirementType_, *integer* _quantity_, *integer* _param1_, *integer* _param2_) +* GetTributePatronRequirementTargetingText(*[TributePatronRequirement|#TributePatronRequirement]* _requirementType_, *integer* _quantity_, *integer* _param1_, *integer* _param2_, *string* _targetingFormatterOverrideText_) ** _Returns:_ *string* _targetingText_ * GetNumTributePatrons() @@ -19934,6 +20031,9 @@ h2. Game API * DoesTributeCardHaveTriggerMechanic(*integer* _cardDefId_) ** _Returns:_ *bool* _hasTriggerMechanic_ +* DoesTributeCardHaveMechanicType(*integer* _cardDefId_, *[TributeMechanic|#TributeMechanic]* _mechanicType_) +** _Returns:_ *bool* _hasMechanicType_ + * GetTributeCardFlavorText(*integer* _cardDefId_) ** _Returns:_ *string* _flavorText_ @@ -21091,6 +21191,9 @@ Objects that inherit behavior from *Control* * GetFlexMargin(*[FlexEdge|#FlexEdge]* _edge_) ** _Returns:_ *number* _margin_ +* GetFlexPadding(*[FlexEdge|#FlexEdge]* _edge_) +** _Returns:_ *number* _padding_ + * GetFlexShrink() ** _Returns:_ *number* _shrink_ @@ -21194,13 +21297,13 @@ Objects that inherit behavior from *Control* ** _Returns:_ *[AxisRotationOrder|#AxisRotationOrder]* _order_ * GetTransformScale() -** _Returns:_ *number* _scaleX_, *number* _scaleY_ +** _Returns:_ *number* _scaleX_, *number* _scaleY_, *number* _scaleZ_ * GetTransformSkew() ** _Returns:_ *number* _skewXRadians_, *number* _skewYRadians_ * GetType() -** _Returns:_ *integer* _type_ +** _Returns:_ *[ControlType|#ControlType]* _type_ * GetWave() ** _Returns:_ *number* _angleRadians_, *number* _frequency_, *number* _speed_, *number* _offset_ @@ -21345,6 +21448,8 @@ Objects that inherit behavior from *Control* * SetFlexMargins(*number* _left_, *number* _top_, *number* _right_, *number* _bottom_) +* SetFlexPaddings(*number* _left_, *number* _top_, *number* _right_, *number* _bottom_) + * SetFlexShrink(*number* _shrink_) * SetGaussianBlur(*integer* _kernelSize_, *number* _factor_) @@ -21433,6 +21538,8 @@ Objects that inherit behavior from *Control* * SetTransformScaleY(*number* _scaleY_) +* SetTransformScaleZ(*number* _scaleZ_) + * SetTransformSkew(*number* _skewXRadians_, *number* _skewYRadians_) * SetTransformSkewX(*number* _skewXRadians_) @@ -22434,6 +22541,8 @@ h3. TooltipControl * SetTributePatronStarterCard(*integer* _patronId_, *luaindex* _cardIndex_) +* SetTributePatronWithFavorState(*integer* _patronId_, *[TributePatronPerspectiveFavorState|#TributePatronPerspectiveFavorState]* _highlightFavorState_) + * SetTributeSeasonRewardList(*[TributeTier|#TributeTier]* _tributeTier_, *integer* _rewardListId_) * SetVerticalPadding(*number* _paddingY_) @@ -22792,6 +22901,7 @@ h2. Events * EVENT_COLLECTIBLE_RENAME_ERROR (*[NamingError|#NamingError]* _errorReason_) * EVENT_COLLECTIBLE_REQUEST_BROWSE_TO (*integer* _collectibleId_) * EVENT_COLLECTIBLE_SET_IN_WATER_ALERT +* EVENT_COLLECTIBLE_USER_FLAGS_UPDATED (*integer* _collectibleId_, *integer* _oldFlags_, *integer* _newFlags_) * EVENT_COLLECTIBLE_USE_RESULT (*[CollectibleUsageBlockReason|#CollectibleUsageBlockReason]* _result_, *bool* _isAttemptingActivation_) * EVENT_COLLECTION_UPDATED * EVENT_COMBAT_EVENT (*[ActionResult|#ActionResult]* _result_, *bool* _isError_, *string* _abilityName_, *integer* _abilityGraphic_, *[ActionSlotType|#ActionSlotType]* _abilityActionSlotType_, *string* _sourceName_, *[CombatUnitType|#CombatUnitType]* _sourceType_, *string* _targetName_, *[CombatUnitType|#CombatUnitType]* _targetType_, *integer* _hitValue_, *[CombatMechanicFlags|#CombatMechanicFlags]* _powerType_, *[DamageType|#DamageType]* _damageType_, *bool* _log_, *integer* _sourceUnitId_, *integer* _targetUnitId_, *integer* _abilityId_, *integer* _overflow_) @@ -22950,6 +23060,7 @@ h2. Events * EVENT_GUILD_FINDER_SEARCH_COOLDOWN_UPDATE (*integer* _cooldownMs_) * EVENT_GUILD_ID_CHANGED (*string* _unitTag_, *integer* _oldGuildId_, *integer* _newGuildId_) * EVENT_GUILD_INFO_REQUEST_COMPLETE (*integer* _guildId_) +* EVENT_GUILD_KEEP_ATTACK_UPDATE (*[ChannelType|#ChannelType]* _channel_, *integer* _numGuardsKilled_, *integer* _numAttackers_, *string* _location_) * EVENT_GUILD_KIOSK_ACTIVE_BIDS_RESPONSE (*integer* _guildId_, *[SocialActionResult|#SocialActionResult]* _result_) * EVENT_GUILD_KIOSK_CONSIDER_BID_START * EVENT_GUILD_KIOSK_CONSIDER_BID_STOP @@ -23188,6 +23299,9 @@ h2. Events * EVENT_RAID_TRIAL_SCORE_UPDATE (*[RaidPointReason|#RaidPointReason]* _scoreUpdateReason_, *integer* _scoreAmount_, *integer* _totalScore_) * EVENT_RAID_TRIAL_STARTED (*string* _trialName_, *bool* _weekly_) * EVENT_RAM_ESCORT_COUNT_UPDATE (*integer* _numEscorts_) +* EVENT_RANDOM_DICE_ROLL (*string* _displayName_, *string* _characterName_, *integer* _maxValue_, *integer* _numDice_, *integer* _modifier_, *integer* _rollResult_) +* EVENT_RANDOM_MOUNT_SETTING_CHANGED (*[RandomMountType|#RandomMountType]* _playerRandomMountType_, *[RandomMountType|#RandomMountType]* _companionRandomMountType_) +* EVENT_RANDOM_RANGE_ROLL (*string* _displayName_, *string* _characterName_, *integer* _minValue_, *integer* _maxValue_, *integer* _rollResult_) * EVENT_RANK_POINT_UPDATE (*string* _unitTag_, *integer* _rankPoints_, *integer* _difference_) * EVENT_RECALL_KEEP_USE_RESULT (*[KeepRecallStoneUseResult|#KeepRecallStoneUseResult]* _result_) * EVENT_RECIPE_ALREADY_KNOWN @@ -23413,7 +23527,6 @@ h2. Events * EVENT_FRIEND_CHARACTER_UPDATED (*string* _displayName_) * EVENT_FRIEND_CHARACTER_ZONE_CHANGED (*string* _displayName_, *string* _characterName_, *string* _zoneName_) * EVENT_FRIEND_DISPLAY_NAME_CHANGED (*string* _oldDisplayName_, *string* _newDisplayName_) -* EVENT_FRIEND_HERON_INFO_BATCH_UPDATED * EVENT_FRIEND_NOTE_UPDATED (*string* _displayName_, *string* _note_) * EVENT_FRIEND_PLAYER_STATUS_CHANGED (*string* _displayName_, *string* _characterName_, *[PlayerStatus|#PlayerStatus]* _oldStatus_, *[PlayerStatus|#PlayerStatus]* _newStatus_) * EVENT_FRIEND_REMOVED (*string* _displayName_) @@ -23457,7 +23570,6 @@ h2. Events * EVENT_GUILD_SELF_JOINED_GUILD (*integer* _guildServerId_, *string* _characterName_, *integer* _guildId_) * EVENT_GUILD_SELF_LEFT_GUILD (*integer* _guildServerId_, *string* _characterName_, *integer* _guildId_) * EVENT_GUILD_TRADER_HIRED_UPDATED (*integer* _guildId_) -* EVENT_HERON_URL_REQUESTED (*string* _urlString_) * EVENT_IGNORE_ADDED (*string* _displayName_) * EVENT_IGNORE_NOTE_UPDATED (*string* _displayName_, *string* _note_) * EVENT_IGNORE_ONLINE_CHARACTER_CHANGED (*string* _displayName_) @@ -23502,7 +23614,7 @@ h2. Events * EVENT_KEYBINDINGS_LOADED * EVENT_KEYBINDING_CLEARED (*luaindex* _layerIndex_, *luaindex* _categoryIndex_, *luaindex* _actionIndex_, *luaindex* _bindingIndex_) * EVENT_KEYBINDING_SET (*luaindex* _layerIndex_, *luaindex* _categoryIndex_, *luaindex* _actionIndex_, *luaindex* _bindingIndex_, *[KeyCode|#KeyCode]* _keyCode_, *[KeyCode|#KeyCode]* _mod1_, *[KeyCode|#KeyCode]* _mod2_, *[KeyCode|#KeyCode]* _mod3_, *[KeyCode|#KeyCode]* _mod4_) -* EVENT_LUA_ERROR (*string* _error_) +* EVENT_LUA_ERROR (*string* _error_, *integer* _errorCode_) * EVENT_SCREEN_RESIZED (*integer* _width_, *integer* _height_) * EVENT_SCRIPT_ACCESS_VIOLATION (*string* _protectedFunctionName_) * EVENT_SECURE_3D_RENDER_MODE_CHANGED (*bool* _enabled_) @@ -23927,6 +24039,7 @@ h5. Control * [Child: Dimensions|#Dimensions] * [Child: FadeGradient|#FadeGradient] * [Child: FlexMargin|#FlexMargin] +* [Child: FlexPadding|#FlexPadding] * [Child: GaussianBlur|#GaussianBlur] * [Child: HitInsets|#HitInsets] * [Child: MotionBlur|#MotionBlur] @@ -24110,6 +24223,12 @@ h5. FlexMargin * _attribute:_ *number* _right_ * _attribute:_ *number* _bottom_ +h5. FlexPadding +* _attribute:_ *number* _left_ +* _attribute:_ *number* _top_ +* _attribute:_ *number* _right_ +* _attribute:_ *number* _bottom_ + h5. Font * _attribute:_ *string* _name_ * _attribute:_ *bool* _virtual_ @@ -24759,6 +24878,7 @@ h5. TransformRotationAnimation h5. TransformScale * _attribute:_ *number* _x_ * _attribute:_ *number* _y_ +* _attribute:_ *number* _z_ * _attribute:_ *number* _scale_ h5. TransformScaleAnimation diff --git a/README.md b/README.md index bc1f2b529..7605cea49 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ If you're a Zenimax Media Inc. representative and have any objection to any of t This repo is also available at http://www.esoui.com/downloads/info1213-ESOUI-TheElderScrollsOnlinesourcecode.html -**Last update: 8.3.7 (API 101037) on 11 Apr 2023.** +**Last update: 9.0.0 (API 101038) on 17 Apr 2023.** *Join ESOUI Dev Community on Gitter :* diff --git a/bin/update b/bin/update index 3df8ec141..649ab4b3b 100644 --- a/bin/update +++ b/bin/update @@ -2,7 +2,7 @@ set -ue -git checkout master +git checkout pts9.0 find esoui/ -type f -name "*.dds" > Textures.txt grep -Phor 'EsoUI[^"]+?\.dds' esoui/ >> Textures.txt cat Textures.txt | tr '[A-Z]\\' '[a-z]/' | sort -u > 1.txt diff --git a/esoui/app/loadingscreen/gamepad/gamepadloadingscreen.lua b/esoui/app/loadingscreen/gamepad/gamepadloadingscreen.lua index 70deb75eb..ba1bdc399 100755 --- a/esoui/app/loadingscreen/gamepad/gamepadloadingscreen.lua +++ b/esoui/app/loadingscreen/gamepad/gamepadloadingscreen.lua @@ -36,6 +36,11 @@ end function LoadingScreen_Gamepad:OnLongLoadTime(event) if not self:IsHidden() then self.longLoadAnimation:PlayFromStart() + if IsScreenNarrationEnabled() then + --Add the narration for the long load text + AddPendingNarrationText(GetString(SI_LONG_LOAD_TIME)) + RequestReadPendingNarrationTextToClient(NARRATION_TYPE_UI_SCREEN) + end end end diff --git a/esoui/app/loadingscreen/sharedloadingscreen.lua b/esoui/app/loadingscreen/sharedloadingscreen.lua index dd44d5ad6..7a28ccd65 100755 --- a/esoui/app/loadingscreen/sharedloadingscreen.lua +++ b/esoui/app/loadingscreen/sharedloadingscreen.lua @@ -91,7 +91,11 @@ function LoadingScreen_Base:Initialize() EVENT_MANAGER:RegisterForEvent(self:GetSystemName(), EVENT_DISCONNECTED_FROM_SERVER, function(...) self:OnDisconnectedFromServer(...) end) EVENT_MANAGER:RegisterForEvent(self:GetSystemName(), EVENT_RESUME_FROM_SUSPEND, function(...) self:OnResumeFromSuspend(...) end) - local function OnSubsystemLoadComplete(eventCode, system) + local function OnSubsystemLoadStateChanged(eventCode, system, isComplete) + if not isComplete then + return + end + self:Log(string.format("Load Screen - %s Complete", GetLoadingSystemName(system))) if GetNumTotalSubsystemsToLoad() == GetNumLoadedSubsystems() then if not IsWaitingForTeleport() then @@ -103,7 +107,7 @@ function LoadingScreen_Base:Initialize() end else local remainingText = "Load Screen - Waiting On: " - for i = 1, GetNumTotalSubsystemsToLoad() do + for i = LOADING_SYSTEM_ITERATION_BEGIN, LOADING_SYSTEM_ITERATION_END do if not IsSystemLoaded(i) then remainingText = remainingText .. GetLoadingSystemName(i) .. ", " end @@ -112,7 +116,7 @@ function LoadingScreen_Base:Initialize() end end - EVENT_MANAGER:RegisterForEvent(self:GetSystemName(), EVENT_SUBSYSTEM_LOAD_COMPLETE, OnSubsystemLoadComplete) + EVENT_MANAGER:RegisterForEvent(self:GetSystemName(), EVENT_SUBSYSTEM_LOAD_STATE_CHANGED, OnSubsystemLoadStateChanged) self:SizeLoadingTexture() self:InitializeAnimations() diff --git a/esoui/common/common.txt b/esoui/common/common.txt index c57925cc9..c90196585 100755 --- a/esoui/common/common.txt +++ b/esoui/common/common.txt @@ -29,8 +29,6 @@ EsoUI\Common\Console\AutoSaving_Console.xml EsoUI\Common\Console\ZO_PlayerConsoleInfoRequestManager.lua EsoUI\Common\Console\ZO_PlayerConsoleRequestsUtils.lua -EsoUI\Common\Heron\HeronURLManager.lua - EsoUI\Common\Gamepad\GenericHeaders\GenericHeaders.lua EsoUI\Common\Gamepad\GenericHeaders\GenericHeaders.xml EsoUI\Common\Gamepad\GenericFooters\GenericFooters.lua diff --git a/esoui/common/gamepad/genericheaders/genericheaders.lua b/esoui/common/gamepad/genericheaders/genericheaders.lua index 2167997f1..3dc98d5d0 100755 --- a/esoui/common/gamepad/genericheaders/genericheaders.lua +++ b/esoui/common/gamepad/genericheaders/genericheaders.lua @@ -658,7 +658,12 @@ function ZO_GamepadGenericHeader_Refresh(control, data, blockTabBarCallbacks) control.tabBar:Clear() if data.tabBarEntries then for i, tabData in ipairs(data.tabBarEntries) do - if (tabData.visible == nil) or tabData.visible() then + local visible = tabData.visible + if type(visible) == "function" then + visible = visible() + end + + if visible ~= false then if tabData.template then control.tabBar:AddEntry(tabData.template, tabData) else diff --git a/esoui/common/gamepad/genericheaders/genericheaders.xml b/esoui/common/gamepad/genericheaders/genericheaders.xml index b6eace235..876eefdcb 100755 --- a/esoui/common/gamepad/genericheaders/genericheaders.xml +++ b/esoui/common/gamepad/genericheaders/genericheaders.xml @@ -10,7 +10,7 @@ - + @@ -62,6 +62,39 @@ self:SetTextureSource(GetGamepadLeftStickSlideAndScrollIcon) + + @@ -90,6 +123,19 @@ self:SetTextureSource(GetGamepadRightStickScrollIcon) + + diff --git a/esoui/common/zo_keybindstrip/keybindstrip.lua b/esoui/common/zo_keybindstrip/keybindstrip.lua index 397d1be27..8cc7c830b 100755 --- a/esoui/common/zo_keybindstrip/keybindstrip.lua +++ b/esoui/common/zo_keybindstrip/keybindstrip.lua @@ -56,8 +56,9 @@ KEYBIND_STRIP_WITH_GENERIC_FOOTER_GAMEPAD_STYLE.rightAnchorRelativePoint = LEFT KEYBIND_STRIP_WITH_GENERIC_FOOTER_GAMEPAD_STYLE.rightAnchorOffset = -24 function ZO_KeybindStrip_OnInitialized(control) + local style = IsInGamepadPreferredMode() and KEYBIND_STRIP_GAMEPAD_STYLE or KEYBIND_STRIP_STANDARD_STYLE - KEYBIND_STRIP = ZO_KeybindStrip:New(control, "ZO_KeybindStripButtonTemplate", KEYBIND_STRIP_STANDARD_STYLE) + KEYBIND_STRIP = ZO_KeybindStrip:New(control, "ZO_KeybindStripButtonTemplate", style) local defaultExit = { name = GetString(SI_EXIT_BUTTON), diff --git a/esoui/common/zo_uierrors/errorframe.lua b/esoui/common/zo_uierrors/errorframe.lua index d0cbe51f8..90f8a3b5f 100755 --- a/esoui/common/zo_uierrors/errorframe.lua +++ b/esoui/common/zo_uierrors/errorframe.lua @@ -2,46 +2,205 @@ --[[ ZO_ErrorFrame ]]-- -- -local ZO_ErrorFrame = ZO_Object:Subclass() - -function ZO_ErrorFrame:New(...) - local errorFrame = ZO_Object.New(self) - errorFrame:Initialize(...) - return errorFrame -end +local ZO_ErrorFrame = ZO_InitializingObject:Subclass() function ZO_ErrorFrame:Initialize(control) self.control = control self.textEditControl = control:GetNamedChild("TextEdit") - self.titleControl = control:GetNamedChild("Title") - self.dismissControl = control:GetNamedChild("Dismiss") - self.dismissKeybind = self.dismissControl:GetNamedChild("Keybind") - self.dismissKeybind:SetKeybind("UI_SHORTCUT_PRIMARY") - self.moreInfoButton = control:GetNamedChild("MoreInfo") - ZO_CheckButton_SetToggleFunction(self.moreInfoButton, function() - self.moreInfo = not self.moreInfo - SetCVar("UIErrorShowMoreInfo", self.moreInfo and "1" or "0") - self:RefreshErrorText() + self.titleControl = control:GetNamedChild("HeaderTitle") + self.footerRow1 = control:GetNamedChild("FooterRow1") + self.footerRow2 = control:GetNamedChild("FooterRow2") + + self.closeButton = control:GetNamedChild("Close") + self.copyErrorCodeButton = control:GetNamedChild("CopyCode") + + self.moreInfoContainer = self.footerRow1:GetNamedChild("MoreInfo") + self.moreInfoCheckButton = self.moreInfoContainer:GetNamedChild("CheckButton") + ZO_CheckButton_SetToggleFunction(self.moreInfoCheckButton, function() + self:ToggleMoreInfo() end) - self.queuedErrors = {} + self.pageSpinnerControl = self.footerRow1:GetNamedChild("PageSpinner") + ZO_KeyControl_OnInitialized(self.pageSpinnerControl:GetNamedChild("Decrease")) + ZO_KeyControl_OnInitialized(self.pageSpinnerControl:GetNamedChild("Increase")) + self.pageSpinner = ZO_SpinnerWithLabels:New(self.pageSpinnerControl) + self.pageSpinner:SetValueFormatFunction(function(value) + local maxValue = self.pageSpinner:GetMax() + return zo_strformat(SI_UI_ERROR_PAGE_FORMATTER, value, maxValue) + end) + + self.pageSpinner:RegisterCallback("OnValueChanged", function(newValue) + self:RefreshPageSpinner() + --If we are currently displaying the error frame, set the currently viewed error to the new value + if self.displayingError then + self:SetCurrentError(newValue) + end + end) + + self.control:SetHandler("OnUpdate", function() + --If the UI Error action layer is not currently on top, remove and re-add it so it is on top again + if self.displayingError and not IsActionLayerTopLayerByName("UIError") then + RemoveActionLayerByName("UIError") + PushActionLayerByName("UIError") + end + end) + + self.currentErrors = {} + self.suppressedErrors = {} self.suppressErrorDialog = false self.displayingError = false + self.advancedMode = ShouldShowAdvancedUIErrors() self.moreInfo = GetCVar("UIErrorShowMoreInfo") == "1" - ZO_CheckButton_SetCheckState(self.moreInfoButton, self.moreInfo) + ZO_CheckButton_SetCheckState(self.moreInfoCheckButton, self.moreInfo) + self:InitializeKeybinds() self:InitializePlatformStyles() self:InitializeNarrationInfo() EVENT_MANAGER:RegisterForEvent("ErrorFrame", EVENT_LUA_ERROR, function(eventCode, ...) self:OnUIError(...) end) end +function ZO_ErrorFrame:InitializeKeybinds() + self.copyKeybind = self.footerRow2:GetNamedChild("Copy") + self.dismissKeybind = self.footerRow2:GetNamedChild("CenterParentDismiss") + self.suppressKeybind = self.footerRow2:GetNamedChild("CenterParentSuppress") + self.reloadKeybind = self.footerRow2:GetNamedChild("Reload") + self.moreInfoKeybind = self.moreInfoContainer:GetNamedChild("KeybindButton") + self.decreaseKeyLabel = self.pageSpinnerControl:GetNamedChild("DecreaseKeyLabel") + self.increaseKeyLabel = self.pageSpinnerControl:GetNamedChild("IncreaseKeyLabel") + + self.dismissKeybindDescriptor = + { + keybind = "UI_ERROR_DISMISS", + name = GetString(SI_DISMISS_UI_ERROR), + callback = function() + self:DismissErrors() + end, + } + self.dismissKeybind:SetKeybindButtonDescriptor(self.dismissKeybindDescriptor) + + self.suppressKeybindDescriptor = + { + keybind = "UI_ERROR_SUPPRESS", + name = GetString(SI_UI_ERROR_SUPPRESS), + callback = function() + self:SuppressErrors() + end, + } + self.suppressKeybind:SetKeybindButtonDescriptor(self.suppressKeybindDescriptor) + + self.reloadKeybindDescriptor = + { + keybind = "UI_ERROR_RELOAD_UI", + name = GetString(SI_UI_ERROR_RELOAD_UI), + callback = function() + if ZO_IsInternalIngameUI() then + --Passing in "ingame" will reload both ingame *and* internal ingame + ReloadUI("ingame") + else + ReloadUI() + end + end, + } + self.reloadKeybind:SetKeybindButtonDescriptor(self.reloadKeybindDescriptor) + + self.copyKeybindDescriptor = + { + keybind = "UI_ERROR_COPY", + name = GetString(SI_UI_ERROR_COPY), + callback = function() + self:CopyErrorToClipboard() + end, + } + self.copyKeybind:SetKeybindButtonDescriptor(self.copyKeybindDescriptor) + + self.moreInfoKeybindDescriptor = + { + keybind = "UI_ERROR_MORE_INFO", + name = function() + if self.moreInfo then + return GetString(SI_UI_ERROR_LESS_INFO) + else + return GetString(SI_UI_ERROR_MORE_INFO) + end + end, + callback = function() + self:ToggleMoreInfo() + end, + } + self.moreInfoKeybind:SetKeybindButtonDescriptor(self.moreInfoKeybindDescriptor) + + + --These two are clickable keybind labels, NOT keybind buttons + self.increaseKeyLabelDescriptor = + { + keybind = "UI_ERROR_PAGE_RIGHT", + callback = function() + self:CycleRight() + end, + } + self.increaseKeyLabel:SetKeybindButtonDescriptor(self.increaseKeyLabelDescriptor) + + self.decreaseKeyLabelDescriptor = + { + keybind = "UI_ERROR_PAGE_LEFT", + callback = function() + self:CycleLeft() + end, + } + self.decreaseKeyLabel:SetKeybindButtonDescriptor(self.decreaseKeyLabelDescriptor) +end + +function ZO_ErrorFrame:ToggleMoreInfo() + if self.advancedMode then + self.moreInfo = not self.moreInfo + SetCVar("UIErrorShowMoreInfo", self.moreInfo and "1" or "0") + --Re-apply the descriptor in order to refresh the name + self.moreInfoKeybind:SetKeybindButtonDescriptor(self.moreInfoKeybindDescriptor) + ZO_CheckButton_SetCheckState(self.moreInfoCheckButton, self.moreInfo) + self:RefreshErrorText() + --Re-narrate when the toggle changes + SCREEN_NARRATION_MANAGER:QueueCustomEntry("errorFrame") + return true + else + return false + end +end + function ZO_ErrorFrame:UpdatePlatformStyles() + local isGamepad = IsInGamepadPreferredMode() + local normalKeybindTextColor = isGamepad and ZO_SELECTED_TEXT or ZO_NORMAL_TEXT + ApplyTemplateToControl(self.textEditControl, ZO_GetPlatformTemplate("ZO_ErrorFrameTextEdit")) ApplyTemplateToControl(self.titleControl, ZO_GetPlatformTemplate("ZO_ErrorFrameTitle")) - ApplyTemplateToControl(self.dismissControl, ZO_GetPlatformTemplate("ZO_ErrorFrameDismiss")) + ApplyTemplateToControl(self.dismissKeybind, ZO_GetPlatformTemplate("ZO_KeybindButton")) + --Reset the text here to handle the force uppercase on gamepad + self.dismissKeybind:SetText(GetString(SI_DISMISS_UI_ERROR)) + self.dismissKeybind:SetNormalTextColor(normalKeybindTextColor) + + ApplyTemplateToControl(self.suppressKeybind, ZO_GetPlatformTemplate("ZO_KeybindButton")) + --Reset the text here to handle the force uppercase on gamepad + self.suppressKeybind:SetText(GetString(SI_UI_ERROR_SUPPRESS)) + self.suppressKeybind:SetNormalTextColor(normalKeybindTextColor) + + ApplyTemplateToControl(self.reloadKeybind, ZO_GetPlatformTemplate("ZO_KeybindButton")) + --Reset the text here to handle the force uppercase on gamepad + self.reloadKeybind:SetText(GetString(SI_UI_ERROR_RELOAD_UI)) + self.reloadKeybind:SetNormalTextColor(normalKeybindTextColor) + + ApplyTemplateToControl(self.copyKeybind, ZO_GetPlatformTemplate("ZO_KeybindButton")) + --Reset the text here to handle the force uppercase on gamepad + self.copyKeybind:SetText(GetString(SI_UI_ERROR_COPY)) + self.copyKeybind:SetNormalTextColor(normalKeybindTextColor) + + ApplyTemplateToControl(self.moreInfoContainer, ZO_GetPlatformTemplate("ZO_ErrorFrameMoreInfo")) + self.moreInfoKeybind:SetNormalTextColor(normalKeybindTextColor) + + local spinnerFont = isGamepad and "ZoFontGamepad34" or "ZoFontWinH2" + self.pageSpinner:SetFont(spinnerFont) + self:RefreshPageSpinner() end function ZO_ErrorFrame:InitializePlatformStyles() @@ -55,18 +214,54 @@ function ZO_ErrorFrame:InitializeNarrationInfo() return self.displayingError end, selectedNarrationFunction = function() - return SCREEN_NARRATION_MANAGER:CreateNarratableObject(GetString(SI_WINDOW_TITLE_UI_ERROR)) + local narrations = {} + ZO_AppendNarration(narrations, SCREEN_NARRATION_MANAGER:CreateNarratableObject(self.titleText)) + + if not self.pageSpinnerControl:IsHidden() then + ZO_AppendNarration(narrations, SCREEN_NARRATION_MANAGER:CreateNarratableObject(self.pageSpinner:GetFormattedValueText())) + end + return narrations end, additionalInputNarrationFunction = function() local narrationData = {} - local dismissButtonNarrationData = - { - name = GetString(SI_DISMISS_UI_ERROR), - keybindName = ZO_Keybindings_GetHighestPriorityNarrationStringFromAction("UI_SHORTCUT_PRIMARY") or GetString(SI_ACTION_IS_NOT_BOUND), - enabled = true, - } - table.insert(narrationData, dismissButtonNarrationData) + if not self.moreInfoKeybind:IsHidden() then + table.insert(narrationData, self.moreInfoKeybind:GetKeybindButtonNarrationData()) + end + + if not self.copyKeybind:IsHidden() then + table.insert(narrationData, self.copyKeybind:GetKeybindButtonNarrationData()) + end + + if not self.dismissKeybind:IsHidden() then + table.insert(narrationData, self.dismissKeybind:GetKeybindButtonNarrationData()) + end + + if not self.suppressKeybind:IsHidden() then + table.insert(narrationData, self.suppressKeybind:GetKeybindButtonNarrationData()) + end + + if not self.reloadKeybind:IsHidden() then + table.insert(narrationData, self.reloadKeybind:GetKeybindButtonNarrationData()) + end + + if not self.pageSpinnerControl:IsHidden() then + local pageLeftNarrationData = + { + name = GetString(SI_GAMEPAD_PAGED_LIST_PAGE_LEFT_NARRATION), + keybindName = ZO_Keybindings_GetHighestPriorityNarrationStringFromAction("UI_ERROR_PAGE_LEFT") or GetString(SI_ACTION_IS_NOT_BOUND), + enabled = self.pageSpinner:IsDecreaseEnabled(), + } + table.insert(narrationData, pageLeftNarrationData) + + local pageRightNarrationData = + { + name = GetString(SI_GAMEPAD_PAGED_LIST_PAGE_RIGHT_NARRATION), + keybindName = ZO_Keybindings_GetHighestPriorityNarrationStringFromAction("UI_ERROR_PAGE_RIGHT") or GetString(SI_ACTION_IS_NOT_BOUND), + enabled = self.pageSpinner:IsIncreaseEnabled(), + } + table.insert(narrationData, pageRightNarrationData) + end return narrationData end, @@ -74,80 +269,258 @@ function ZO_ErrorFrame:InitializeNarrationInfo() SCREEN_NARRATION_MANAGER:RegisterCustomObject("errorFrame", narrationInfo) end -function ZO_ErrorFrame:GetNextQueuedError() - if #self.queuedErrors > 0 then - return table.remove(self.queuedErrors, 1) +function ZO_ErrorFrame:GetError(errorIndex) + return self.currentErrors[errorIndex] +end + +function ZO_ErrorFrame:AddError(errorString, errorCode) + --If the error code is nil it should always be unique + if errorCode ~= nil then + for _, errorData in ipairs(self.currentErrors) do + if errorData.errorCode == errorCode then + errorData.count = errorData.count + 1 + return + end + end + end + + local errorData = + { + errorString = errorString, + errorCode = errorCode, + count = 1, + } + table.insert(self.currentErrors, errorData) + + --If we are in advanced mode and already viewing the error frame, re-narrate when a new error is added + if self.displayingError and self.advancedMode then + SCREEN_NARRATION_MANAGER:QueueCustomEntry("errorFrame") end end -function ZO_ErrorFrame:OnUIError(errorString) - if not self.suppressErrorDialog and errorString then - table.insert(self.queuedErrors, errorString) +function ZO_ErrorFrame:RefreshAdvancedMode() + local advancedMode = ShouldShowAdvancedUIErrors() + if advancedMode ~= self.advancedMode then + --If the advanced mode setting changed, clear all suppressed errors + ZO_ClearTable(self.suppressedErrors) + self.advancedMode = advancedMode + end +end - if not self.displayingError then - self.displayingError = true - self.control:SetHidden(false) - local fullError = self:GetNextQueuedError() +function ZO_ErrorFrame:RefreshPageSpinner() + local numErrors = #self.currentErrors + --Order matters. Set the min and max first so we don't stomp the hidden state of the buttons that we set below + self.pageSpinner:SetMinMax(1, numErrors) + + local isGamepad = IsInGamepadPreferredMode() + self.pageSpinner.decreaseButton:SetHidden(isGamepad) + self.pageSpinner.increaseButton:SetHidden(isGamepad) + self.pageSpinner.decreaseKeyLabel:SetHidden(not isGamepad) + self.pageSpinner.increaseKeyLabel:SetHidden(not isGamepad) + + --Show the page spinner if we have at least 2 errors and are in advanced mode + self.pageSpinnerControl:SetHidden(numErrors <= 1 or not self.advancedMode) + + --Because we include the max as part of the value display, we need to update the display after setting the min and max + self.pageSpinner:UpdateDisplay() +end - --Colored Full Error: Wrap the ... section with color markup - self.coloredFullError = string.gsub(fullError, ".-", function(match) - return "|caaaaaa"..match.."|r" - end) +function ZO_ErrorFrame:SetCurrentError(errorIndex) + local errorData = self:GetError(errorIndex) + local fullError = errorData.errorString + local rawErrorCode = errorData.errorCode + + self.currentErrorIndex = errorIndex + + --Colored Full Error: Wrap the ... section with color markup + self.coloredFullError = string.gsub(fullError, ".-", function(match) + return "|caaaaaa"..match.."|r" + end) - --Copy Error : Tab the ... section for easier reading. - self.copyError = string.gsub(fullError, ".-", function(match) - return "\t"..match - end) + --Copy Error : Tab the ... section for easier reading. + self.copyError = string.gsub(fullError, ".-", function(match) + return "\t"..match + end) + + --Simple Error: Remove the ... section and any newline after it if there is one + self.simpleError = string.gsub(fullError, ".-\n?", "") + + --Convert the error code into a hex value + --If we don't have an error code for whatever reason, just use an empty string + if rawErrorCode then + self.errorHexCode = string.format("%X", rawErrorCode) + else + self.errorHexCode = "" + end + + self:RefreshErrorText() + self:RefreshTitleText() + self:RefreshButtons() + --Re-narrate whenever the current error changes + SCREEN_NARRATION_MANAGER:QueueCustomEntry("errorFrame") +end + +function ZO_ErrorFrame:OnUIError(errorString, errorCode) + --First, refresh whether or not we are in advanced mode + self:RefreshAdvancedMode() - --Simple Error: Remove the ... section and any newline after it if there is one - self.simpleError = string.gsub(fullError, ".-\n?", "") + if not self.suppressErrorDialog and not self.suppressedErrors[errorCode] and errorString then + self:AddError(errorString, errorCode) - self:RefreshErrorText() - SCREEN_NARRATION_MANAGER:QueueCustomEntry("errorFrame") + if not self.displayingError then + PushActionLayerByName("UIError") + self.displayingError = true + self.control:SetHidden(false) + self:SetCurrentError(1) + else + --If we are already displaying the error, we only need to refresh the page spinner in case the max value changed and the title text in case the count changed + self:RefreshPageSpinner() + self:RefreshTitleText() end end end function ZO_ErrorFrame:CopyErrorToClipboard() - if self.copyError then + if not IsConsoleUI() and self.advancedMode and self.copyError then CopyToClipboard(self.copyError) + return true + end + + return false +end + +function ZO_ErrorFrame:CopyErrorCodeToClipboard() + if not IsConsoleUI() and self.errorHexCode then + CopyToClipboard(self.errorHexCode) + return true + end + + return false +end + +function ZO_ErrorFrame:RefreshButtons() + self:RefreshPageSpinner() + + --Only show the suppress button in advanced mode + self.suppressKeybind:SetHidden(not self.advancedMode) + + --Only show the more info button in advanced mode + self.moreInfoContainer:SetHidden(not self.advancedMode) + + --Do not show the reload button in pregame + self.reloadKeybind:SetHidden(ZO_IsPregameUI()) + + --Only show the copy button in advanced mode (and not on consoles) + self.copyKeybind:SetHidden(IsConsoleUI() or not self.advancedMode) + + --Do not show the close button on consoles + self.closeButton:SetHidden(IsConsoleUI()) + + --Do not show the copy error code button on consoles + self.copyErrorCodeButton:SetHidden(IsConsoleUI()) +end + +do + local MAX_DISPLAYED_ERROR_COUNT = 99 + function ZO_ErrorFrame:RefreshTitleText() + local errorData = self:GetError(self.currentErrorIndex) + local colorizedErrorHexCode = ZO_SELECTED_TEXT:Colorize(self.errorHexCode) + if self.advancedMode and errorData.count > 1 then + if errorData.count > MAX_DISPLAYED_ERROR_COUNT then + self.titleText = zo_strformat(SI_WINDOW_TITLE_UI_ERROR_MULTIPLE_MAX, MAX_DISPLAYED_ERROR_COUNT, colorizedErrorHexCode) + else + self.titleText = zo_strformat(SI_WINDOW_TITLE_UI_ERROR_MULTIPLE, errorData.count, colorizedErrorHexCode) + end + else + self.titleText = zo_strformat(SI_WINDOW_TITLE_UI_ERROR, colorizedErrorHexCode) + end + + self.titleControl:SetText(self.titleText) end end function ZO_ErrorFrame:RefreshErrorText() if self.simpleError then - self.textEditControl:SetText(self.moreInfo and self.coloredFullError or self.simpleError) + local showFullError = self.moreInfo and self.advancedMode + self.textEditControl:SetText(showFullError and self.coloredFullError or self.simpleError) + self.textEditControl:SetCursorPosition(0) else self.textEditControl:SetText("") end self.textEditControl:SetTopLineIndex(1) end -function ZO_ErrorFrame:HideCurrentError() +function ZO_ErrorFrame:HideErrorFrame(suppressCurrent) + local errorHidden = false if not self.suppressErrorDialog then if self.displayingError then + RemoveActionLayerByName("UIError") self.displayingError = false self.control:SetHidden(true) self.textEditControl:SetText("") + errorHidden = true + + if suppressCurrent then + for _, errorData in ipairs(self.currentErrors) do + --If we don't have an error code for this error, it cannot be suppressed + if errorData.errorCode ~= nil then + self.suppressedErrors[errorData.errorCode] = true + end + end + end + + ZO_ClearTable(self.currentErrors) end - - self:OnUIError(self:GetNextQueuedError()) end + + return errorHidden end -function ZO_ErrorFrame:HideAllErrors() +function ZO_ErrorFrame:ToggleSuppressDialog() if not self.suppressErrorDialog then - self.queuedErrors = {} - self:HideCurrentError() + self:HideErrorFrame() end + + self.suppressErrorDialog = not self.suppressErrorDialog end -function ZO_ErrorFrame:ToggleSupressDialog() - if not self.suppressErrorDialog then - self:HideAllErrors() +function ZO_ErrorFrame:DismissErrors(suppressCurrent) + if self.advancedMode then + --In advanced mode, we will either suppress all current errors or dismiss without suppressing + return self:HideErrorFrame(suppressCurrent) + else + --In simplified mode, we always suppress current errors + local SUPPRESS_CURRENT = true + return self:HideErrorFrame(SUPPRESS_CURRENT) end +end - self.suppressErrorDialog = not self.suppressErrorDialog +function ZO_ErrorFrame:SuppressErrors() + --Only do something if we are in advanced mode + if self.advancedMode then + local SUPPRESS_CURRENT = true + return self:DismissErrors(SUPPRESS_CURRENT) + else + return false + end +end + +function ZO_ErrorFrame:CycleLeft() + if not self.pageSpinnerControl:IsHidden() then + self.pageSpinner:ModifyValue(-1) + return true + end + + return false +end + +function ZO_ErrorFrame:CycleRight() + if not self.pageSpinnerControl:IsHidden() then + self.pageSpinner:ModifyValue(1) + return true + end + + return false end -- XML Handlers @@ -156,14 +529,43 @@ function ZO_UIErrors_Init(control) ZO_ERROR_FRAME = ZO_ErrorFrame:New(control) end -function ZO_UIErrors_HideCurrent() - ZO_ERROR_FRAME:HideCurrentError() +function ZO_UIErrors_CopyError() + return ZO_ERROR_FRAME:CopyErrorToClipboard() +end + +function ZO_UIErrors_CopyCode() + return ZO_ERROR_FRAME:CopyErrorCodeToClipboard() +end + +function ZO_UIErrors_ToggleMoreInfo() + return ZO_ERROR_FRAME:ToggleMoreInfo() +end + +function ZO_UIErrors_Dismiss() + return ZO_ERROR_FRAME:DismissErrors() +end + +function ZO_UIErrors_PageLeft() + return ZO_ERROR_FRAME:CycleLeft() +end + +function ZO_UIErrors_PageRight() + return ZO_ERROR_FRAME:CycleRight() +end + +function ZO_UIErrors_Suppress() + return ZO_ERROR_FRAME:SuppressErrors() +end + +function ZO_UIErrors_ToggleSuppressDialog() + ZO_ERROR_FRAME:ToggleSuppressDialog() end -function ZO_UIErrors_HideAll() - ZO_ERROR_FRAME:HideAllErrors() +function ZO_UIErrors_OnCopyCodeEnter(control) + InitializeTooltip(InformationTooltip, control, LEFT, 0, 0, RIGHT) + SetTooltipText(InformationTooltip, GetString(SI_UI_ERROR_COPY_ERROR_CODE_TOOLTIP)) end -function ZO_UIErrors_ToggleSupressDialog() - ZO_ERROR_FRAME:ToggleSupressDialog() +function ZO_UIErrors_OnCopyCodeExit(control) + ClearTooltip(InformationTooltip) end diff --git a/esoui/common/zo_uierrors/errorframe.xml b/esoui/common/zo_uierrors/errorframe.xml index 34389c73a..cb1272b26 100755 --- a/esoui/common/zo_uierrors/errorframe.xml +++ b/esoui/common/zo_uierrors/errorframe.xml @@ -2,81 +2,161 @@ - diff --git a/esoui/fontstrings/western/defaultfontstrings_western.xml b/esoui/fontstrings/western/defaultfontstrings_western.xml index 0473a4d55..0d656265e 100755 --- a/esoui/fontstrings/western/defaultfontstrings_western.xml +++ b/esoui/fontstrings/western/defaultfontstrings_western.xml @@ -2,7 +2,7 @@ - + diff --git a/esoui/ingame/achievements/gamepad/achievements_gamepad.lua b/esoui/ingame/achievements/gamepad/achievements_gamepad.lua index 481084799..e08d8c571 100755 --- a/esoui/ingame/achievements/gamepad/achievements_gamepad.lua +++ b/esoui/ingame/achievements/gamepad/achievements_gamepad.lua @@ -386,6 +386,19 @@ function ZO_Achievements_Gamepad:InitializeOptionsDialog() local showAllAchievements = CreateEntry(SI_ACHIEVEMENT_FILTER_SHOW_ALL) local showEarnedAchievements = CreateEntry(SI_ACHIEVEMENT_FILTER_SHOW_EARNED) local showUnearnedAchievements = CreateEntry(SI_ACHIEVEMENT_FILTER_SHOW_UNEARNED) + local linkAchievement = ZO_GamepadEntryData:New(zo_strformat(SI_ITEM_ACTION_LINK_TO_CHAT)) + linkAchievement.setup = ZO_SharedGamepadEntry_OnSetup + linkAchievement.callback = function(entryData) + local achievement = entryData.dialog.data.selectedAchievement + ZO_LinkHandler_InsertLinkAndSubmit(ZO_LinkHandler_CreateChatLink(GetAchievementLink, achievement.achievementId)) + ZO_Dialogs_ReleaseDialogOnButtonPress("ACHIEVEMENTS_OPTIONS_GAMEPAD") + end + linkAchievement.visible = function(dialog) + if IsChatSystemAvailableForCurrentPlatform() then + return dialog.data.selectedAchievement ~= nil + end + return false + end self.dialogFilterEntries = { @@ -414,7 +427,7 @@ function ZO_Achievements_Gamepad:InitializeOptionsDialog() { { template = "ZO_GamepadMenuEntryTemplate", - header = SI_GAMEPAD_OPTIONS_MENU, + header = SI_GAMEPAD_ITEM_SETS_BOOK_OPTIONS_FILTERS, entryData = showAllAchievements, }, { @@ -425,6 +438,11 @@ function ZO_Achievements_Gamepad:InitializeOptionsDialog() template = "ZO_GamepadMenuEntryTemplate", entryData = showUnearnedAchievements, }, + { + template = "ZO_GamepadMenuEntryTemplate", + header = GetString(SI_GAMEPAD_ITEM_SETS_BOOK_OPTIONS_ACTIONS), + entryData = linkAchievement, + }, }, buttons = { @@ -501,7 +519,8 @@ function ZO_Achievements_Gamepad:InitializeKeybindStripDescriptors() name = GetString(SI_GAMEPAD_DYEING_OPTIONS), keybind = "UI_SHORTCUT_TERTIARY", callback = function() - ZO_Dialogs_ShowGamepadDialog("ACHIEVEMENTS_OPTIONS_GAMEPAD") + local targetData = self.itemList:GetTargetData() + ZO_Dialogs_ShowGamepadDialog("ACHIEVEMENTS_OPTIONS_GAMEPAD", {selectedAchievement = targetData}) end, visible = function() return self.visibleCategoryId ~= nil diff --git a/esoui/ingame/addoncompatibilityaliases/pc/addoncompatibilityaliases.lua b/esoui/ingame/addoncompatibilityaliases/pc/addoncompatibilityaliases.lua index b7fc01c4e..9f2e6f535 100644 --- a/esoui/ingame/addoncompatibilityaliases/pc/addoncompatibilityaliases.lua +++ b/esoui/ingame/addoncompatibilityaliases/pc/addoncompatibilityaliases.lua @@ -1229,4 +1229,33 @@ function ZO_SharedFurnitureManager:InitializeFurnitureCaches() self:RebuildFurnitureCaches() end -ZO_MaskIterator = ZO_FlagIterator \ No newline at end of file +ZO_MaskIterator = ZO_FlagIterator + +--Error Frame Refactor +ZO_UIErrors_ToggleSupressDialog = ZO_UIErrors_ToggleSuppressDialog +ZO_UIErrors_HideAll = ZO_UIErrors_Dismiss +ZO_UIErrors_HideCurrent = ZO_UIErrors_Dismiss +ZO_ERROR_FRAME.dismissControl = ZO_ERROR_FRAME.dismissKeybind +ZO_ERROR_FRAME.HideAllErrors = function(self) + self:HideErrorFrame() +end +ZO_ERROR_FRAME.HideCurrentError = function(self) + self:HideErrorFrame() +end +ZO_ERROR_FRAME.ToggleSupressDialog = function(self) + self:ToggleSuppressDialog() +end + +-- ZO_SetDefaultCollectibleData rename +ZO_SetDefaultCollectibleData = ZO_SetToDefaultCollectibleData +ZO_CollectibleDataManager.GetSetDefaultCollectibleData = ZO_CollectibleDataManager.GetSetToDefaultCollectibleData +ZO_CompanionCollectionBook_Gamepad.BuildCollectibleCategorySetDefaultData = ZO_CompanionCollectionBook_Gamepad.BuildCollectibleCategorySetToDefaultData + +--LoreReader.lua scene rename +LORE_READER_INTERACTION_SCENE = LORE_READER_DEFAULT_SCENE +GAMEPAD_LORE_READER_INTERACTION_SCENE = GAMEPAD_LORE_READER_DEFAULT_SCENE + +-- Group Size Constants +SMALL_GROUP_SIZE_THRESHOLD = STANDARD_GROUP_SIZE_THRESHOLD +RAID_GROUP_SIZE_THRESHOLD = LARGE_GROUP_SIZE_THRESHOLD +GROUP_SIZE_MAX = MAX_GROUP_SIZE_THRESHOLD diff --git a/esoui/ingame/alerttext/alerthandlers.lua b/esoui/ingame/alerttext/alerthandlers.lua index ce2b706de..6fd78be2a 100755 --- a/esoui/ingame/alerttext/alerthandlers.lua +++ b/esoui/ingame/alerttext/alerthandlers.lua @@ -283,7 +283,6 @@ local AlertHandlers = [EVENT_GROUP_INVITE_RESPONSE] = function(characterName, response, displayName) if response ~= GROUP_INVITE_RESPONSE_ACCEPTED and response ~= GROUP_INVITE_RESPONSE_CONSIDERING_OTHER and response ~= GROUP_INVITE_RESPONSE_IGNORED then - ZO_OutputStadiaLog(string.format("AlertHandlers[EVENT_GROUP_INVITE_RESPONSE], ShouldShowGroupErrorInAlert(response) = %s", (ShouldShowGroupErrorInAlert(response) and "true" or "false"))) if ShouldShowGroupErrorInAlert(response) then local nameToUse if response == GROUP_INVITE_RESPONSE_ALREADY_GROUPED_CANT_JOIN then @@ -1134,6 +1133,17 @@ local AlertHandlers = return ALERT, GetString(SI_TRIBUTE_INVITE_CANCELED), SOUNDS.GENERAL_ALERT_ERROR end, + [EVENT_GUILD_KEEP_ATTACK_UPDATE] = function(_, numGuardsKilled, numAttackers, location) + if tonumber(GetSetting(SETTING_TYPE_UI, UI_SETTING_SHOW_AVA_NOTIFICATIONS)) ~= AVA_NOTIFICATIONS_SETTING_CHOICE_DONT_SHOW and + tonumber(GetSetting(SETTING_TYPE_UI, UI_SETTING_SHOW_GUILD_KEEP_NOTICES)) == GUILD_KEEP_NOTICES_SETTING_CHOICE_ALERT then + if numGuardsKilled > 0 then + return ALERT, zo_strformat(SI_GUILD_KEEP_ATTACK_UPDATE, numGuardsKilled, location, numAttackers) + else + return ALERT, zo_strformat(SI_GUILD_KEEP_ATTACK_END, location) + end + end + end, + [EVENT_HOUSING_PREVIEW_INSPECTION_STATE_CHANGED] = function() local stringId = HousingEditorIsPreviewInspectionEnabled() and SI_HOUSING_PREVIEW_INSPECTION_MODE_ENABLED or SI_HOUSING_PREVIEW_INSPECTION_MODE_DISABLED return ALERT, GetString(stringId) diff --git a/esoui/ingame/armory/armory_manager.lua b/esoui/ingame/armory/armory_manager.lua index 19b9a67df..f423a4bd6 100644 --- a/esoui/ingame/armory/armory_manager.lua +++ b/esoui/ingame/armory/armory_manager.lua @@ -122,6 +122,21 @@ function ZO_Armory_Manager:IsBuildOperationInProgress() return self.currentBuildOperation ~= ARMORY_BUILD_OPERATION_TYPE_NONE end +function ZO_Armory_Manager:SetHideOnBuildOperationComplete(hideOnComplete) + self.hideOnBuildOperationComplete = hideOnComplete +end + +function ZO_Armory_Manager:OnBuildOperationResultClosed() + if self.hideOnBuildOperationComplete then + self.hideOnBuildOperationComplete = false + SCENE_MANAGER:ShowBaseScene() + else + if IsInGamepadPreferredMode() then + ARMORY_GAMEPAD:UpdateKeybinds() + end + end +end + do local GAMPAD_EQUIPMENT_SLOT_TYPES = { diff --git a/esoui/ingame/armory/armorydialogs.lua b/esoui/ingame/armory/armorydialogs.lua index 2449eb435..8944d9cfd 100644 --- a/esoui/ingame/armory/armorydialogs.lua +++ b/esoui/ingame/armory/armorydialogs.lua @@ -49,7 +49,10 @@ ESO_Dialogs["ARMORY_BUILD_RESTORE_FAILED_DIALOG"] = keybind = "DIALOG_NEGATIVE", clickSound = SOUNDS.DIALOG_ACCEPT, } - } + }, + finishedCallback = function() + ZO_ARMORY_MANAGER:OnBuildOperationResultClosed() + end, } ESO_Dialogs["ARMORY_BUILD_RESTORE_SUCCESS_DIALOG"] = @@ -78,14 +81,7 @@ ESO_Dialogs["ARMORY_BUILD_RESTORE_SUCCESS_DIALOG"] = }, }, finishedCallback = function() - if IsInGamepadPreferredMode() then - ARMORY_GAMEPAD:UpdateKeybinds() - end - end, - noChoiceCallback = function() - if IsInGamepadPreferredMode() then - ARMORY_GAMEPAD:UpdateKeybinds() - end + ZO_ARMORY_MANAGER:OnBuildOperationResultClosed() end, } @@ -199,7 +195,10 @@ ESO_Dialogs["ARMORY_BUILD_SAVE_FAILED_DIALOG"] = keybind = "DIALOG_NEGATIVE", clickSound = SOUNDS.DIALOG_ACCEPT, } - } + }, + finishedCallback = function() + ZO_ARMORY_MANAGER:OnBuildOperationResultClosed() + end, } ESO_Dialogs["ARMORY_BUILD_SAVE_SUCCESS_DIALOG"] = @@ -228,14 +227,7 @@ ESO_Dialogs["ARMORY_BUILD_SAVE_SUCCESS_DIALOG"] = } }, finishedCallback = function() - if IsInGamepadPreferredMode() then - ARMORY_GAMEPAD:UpdateKeybinds() - end - end, - noChoiceCallback = function() - if IsInGamepadPreferredMode() then - ARMORY_GAMEPAD:UpdateKeybinds() - end + ZO_ARMORY_MANAGER:OnBuildOperationResultClosed() end, } diff --git a/esoui/ingame/armory/gamepad/armory_gamepad.lua b/esoui/ingame/armory/gamepad/armory_gamepad.lua index b419da9d1..c3cee17a2 100644 --- a/esoui/ingame/armory/gamepad/armory_gamepad.lua +++ b/esoui/ingame/armory/gamepad/armory_gamepad.lua @@ -35,6 +35,10 @@ function ZO_Armory_Gamepad:Initialize(control) ARMORY_ROOT_GAMEPAD_SCENE:SetHideSceneConfirmationCallback(function(scene, nextSceneName, bypassHideSceneConfirmationReason) if ZO_ARMORY_MANAGER:IsBuildOperationInProgress() then ARMORY_ROOT_GAMEPAD_SCENE:RejectHideScene() + --If we tried to hide the scene because the gamepad preferred mode changed, close the armory when the build operation completes to prevent the user from getting stuck in a bad state + if bypassHideSceneConfirmationReason == ZO_BHSCR_GAMEPAD_MODE_CHANGED then + ZO_ARMORY_MANAGER:SetHideOnBuildOperationComplete(true) + end else ARMORY_ROOT_GAMEPAD_SCENE:AcceptHideScene() end diff --git a/esoui/ingame/armory/keyboard/armory_keyboard.lua b/esoui/ingame/armory/keyboard/armory_keyboard.lua index 878f82395..4f4d703f9 100644 --- a/esoui/ingame/armory/keyboard/armory_keyboard.lua +++ b/esoui/ingame/armory/keyboard/armory_keyboard.lua @@ -37,6 +37,10 @@ function ZO_Armory_Keyboard:Initialize(control) ARMORY_KEYBOARD_SCENE:SetHideSceneConfirmationCallback(function(scene, nextSceneName, bypassHideSceneConfirmationReason) if ZO_ARMORY_MANAGER:IsBuildOperationInProgress() then ARMORY_KEYBOARD_SCENE:RejectHideScene() + --If we tried to hide the scene because the gamepad preferred mode changed, close the armory when the build operation completes to prevent the user from getting stuck in a bad state + if bypassHideSceneConfirmationReason == ZO_BHSCR_GAMEPAD_MODE_CHANGED then + ZO_ARMORY_MANAGER:SetHideOnBuildOperationComplete(true) + end else ARMORY_KEYBOARD_SCENE:AcceptHideScene() end diff --git a/esoui/ingame/banking/gamepad/banking_gamepad.lua b/esoui/ingame/banking/gamepad/banking_gamepad.lua index 23beb1967..8e9513d9c 100755 --- a/esoui/ingame/banking/gamepad/banking_gamepad.lua +++ b/esoui/ingame/banking/gamepad/banking_gamepad.lua @@ -497,7 +497,13 @@ function ZO_GamepadBanking:InitializeKeybindStripDescriptors() local collectibleData = ZO_COLLECTIBLE_DATA_MANAGER:GetCollectibleDataById(collectibleId) if collectibleData then local nickname = collectibleData:GetNickname() - ZO_Dialogs_ShowGamepadDialog("GAMEPAD_COLLECTIONS_INVENTORY_RENAME_COLLECTIBLE", { collectibleId = collectibleId, name = nickname }) + local defaultNickname = collectibleData:GetDefaultNickname() + --Only pre-fill the edit text if it's different from the default nickname + local initialEditText = "" + if nickname ~= defaultNickname then + initialEditText = nickname + end + ZO_Dialogs_ShowGamepadDialog("GAMEPAD_COLLECTIONS_INVENTORY_RENAME_COLLECTIBLE", { collectibleId = collectibleId, name = initialEditText, defaultName = defaultNickname }) end end end diff --git a/esoui/ingame/banking/gamepad/bankingcommon_gamepad.lua b/esoui/ingame/banking/gamepad/bankingcommon_gamepad.lua index 7cca6cbf4..3cdb512b8 100755 --- a/esoui/ingame/banking/gamepad/bankingcommon_gamepad.lua +++ b/esoui/ingame/banking/gamepad/bankingcommon_gamepad.lua @@ -199,7 +199,7 @@ function ZO_BankingCommon_Gamepad:InitializeFiltersDialog() dropdown:UpdateItems() - SCREEN_NARRATION_MANAGER:RegisterDialogDropdown(data.dialog, dropdown) + SCREEN_NARRATION_MANAGER:RegisterDialogDropdown(dialog, dropdown) control.dropdown:SelectItemByIndex(withdrawList.currentSortOrderIndex) end, @@ -231,7 +231,7 @@ function ZO_BankingCommon_Gamepad:InitializeFiltersDialog() dropdown:SetNoSelectionText(GetString(SI_GAMEPAD_BANK_FILTER_DEFAULT_TEXT)) dropdown:SetMultiSelectionTextFormatter(GetString(SI_GAMEPAD_BANK_FILTER_DROPDOWN_TEXT)) - SCREEN_NARRATION_MANAGER:RegisterDialogDropdown(data.dialog, dropdown) + SCREEN_NARRATION_MANAGER:RegisterDialogDropdown(dialog, dropdown) local dropdownData = ZO_MultiSelection_ComboBox_Data_Gamepad:New() dropdownData:Clear() diff --git a/esoui/ingame/buffdebuff/buffdebuff.lua b/esoui/ingame/buffdebuff/buffdebuff.lua index a1b4c9489..b676bdcee 100644 --- a/esoui/ingame/buffdebuff/buffdebuff.lua +++ b/esoui/ingame/buffdebuff/buffdebuff.lua @@ -193,7 +193,7 @@ end function ZO_BuffDebuff_ContainerObject:ShouldContextuallyShow() --Don't show while the wheels are up - if UTILITY_WHEEL_MANAGER:IsInteracting() then + if INTERACTIVE_WHEEL_MANAGER:IsInteracting(ZO_INTERACTIVE_WHEEL_TYPE_UTILITY) then return false end diff --git a/esoui/ingame/campaign/campaignbrowser_manager.lua b/esoui/ingame/campaign/campaignbrowser_manager.lua index b86cea11b..ed3a83133 100644 --- a/esoui/ingame/campaign/campaignbrowser_manager.lua +++ b/esoui/ingame/campaign/campaignbrowser_manager.lua @@ -326,7 +326,7 @@ end do local function IsAnyGroupMemberOffline() - for i = 1, GROUP_SIZE_MAX do + for i = 1, MAX_GROUP_SIZE_THRESHOLD do local unitTag = ZO_Group_GetUnitTagForGroupIndex(i) if not IsUnitOnline(unitTag) then return true diff --git a/esoui/ingame/campaign/campaignemperor.xml b/esoui/ingame/campaign/campaignemperor.xml index 3d49c017e..30c911b67 100755 --- a/esoui/ingame/campaign/campaignemperor.xml +++ b/esoui/ingame/campaign/campaignemperor.xml @@ -68,12 +68,12 @@ - + - + diff --git a/esoui/ingame/centerscreenannounce/centerscreenannouncehandlers.lua b/esoui/ingame/centerscreenannounce/centerscreenannouncehandlers.lua index 8ba7704fd..0f012a791 100755 --- a/esoui/ingame/centerscreenannounce/centerscreenannouncehandlers.lua +++ b/esoui/ingame/centerscreenannounce/centerscreenannouncehandlers.lua @@ -1482,7 +1482,7 @@ local CENTER_SCREEN_CALLBACK_HANDLERS = callbackManager = ZO_COLLECTIBLE_DATA_MANAGER, callbackRegistration = "OnCollectionUpdated", callbackFunction = function(collectionUpdateType, collectiblesByUnlockState) - if collectionUpdateType == ZO_COLLECTION_UPDATE_TYPE.UNLOCK_STATE_CHANGES then + if collectionUpdateType == ZO_COLLECTION_UPDATE_TYPE.UNLOCK_STATE_CHANGED then local nowOwnedCollectibles = collectiblesByUnlockState[COLLECTIBLE_UNLOCK_STATE_UNLOCKED_OWNED] if nowOwnedCollectibles then if #nowOwnedCollectibles > MAX_INDIVIDUAL_COLLECTIBLE_UPDATES then diff --git a/esoui/ingame/champion/champion.lua b/esoui/ingame/champion/champion.lua index b27450f49..31ac98693 100644 --- a/esoui/ingame/champion/champion.lua +++ b/esoui/ingame/champion/champion.lua @@ -1261,6 +1261,7 @@ function ChampionPerks:RegisterEvents() self.championBar:RegisterCallback("GamepadFocusChanged", function() self.refreshGroup:MarkDirty("SelectedStarData") + self.refreshGroup:TryClean() end) end diff --git a/esoui/ingame/champion/championassignableactionbar.lua b/esoui/ingame/champion/championassignableactionbar.lua index 62aa94666..d97efcf06 100644 --- a/esoui/ingame/champion/championassignableactionbar.lua +++ b/esoui/ingame/champion/championassignableactionbar.lua @@ -565,10 +565,6 @@ function ZO_ChampionAssignableActionBar_GamepadEditor:UnfocusBar() self.currentSlotIndex = nil self.isFocused = false - if CHAMPION_PERKS:GetChosenConstellation() then - CHAMPION_PERKS:GetChosenConstellation():SelectStar(self.lastSelectedStar) - end - self.bar:RefreshAllSlots() CHAMPION_PERKS:GetGamepadCursor():UpdateVisibility() diff --git a/esoui/ingame/champion/championstar.lua b/esoui/ingame/champion/championstar.lua index 09c04d1d8..39c96b03d 100644 --- a/esoui/ingame/champion/championstar.lua +++ b/esoui/ingame/champion/championstar.lua @@ -793,14 +793,14 @@ function ZO_ChampionStar_OnMouseWheel(control, delta) end function ZO_ChampionStar_OnMouseUp(control, button, upInside) - if IsInGamepadPreferredMode() or control.star:OnClicked(button, upInside) == HANDLED then + if not control.star or IsInGamepadPreferredMode() or control.star:OnClicked(button, upInside) == HANDLED then return end CHAMPION_PERKS:OnCanvasMouseUp(button) end function ZO_ChampionStar_OnDragStart(control, button) - if not IsInGamepadPreferredMode() and button == MOUSE_BUTTON_INDEX_LEFT and GetCursorContentType() == MOUSE_CONTENT_EMPTY then + if control.star and not IsInGamepadPreferredMode() and button == MOUSE_BUTTON_INDEX_LEFT and GetCursorContentType() == MOUSE_CONTENT_EMPTY then control.star:OnDragStart() end end diff --git a/esoui/ingame/chapterupgrade/gamepad/chapterupgrade_gamepad.lua b/esoui/ingame/chapterupgrade/gamepad/chapterupgrade_gamepad.lua index 4dcd0919e..345adac34 100644 --- a/esoui/ingame/chapterupgrade/gamepad/chapterupgrade_gamepad.lua +++ b/esoui/ingame/chapterupgrade/gamepad/chapterupgrade_gamepad.lua @@ -97,11 +97,29 @@ function ZO_ChapterUpgradePane_Gamepad:UpdateKeybinds() ZO_CHAPTER_UPGRADE_GAMEPAD:RefreshKeybinds() end -function ZO_ChapterUpgradePane_Gamepad:OnSelectionChanged() +function ZO_ChapterUpgradePane_Gamepad:OnSelectionChanged(oldData, newData) + ZO_SortFilterList_Gamepad.OnSelectionChanged(self, oldData, newData) local RETAIN_FRAGMENT = true ZO_CHAPTER_UPGRADE_GAMEPAD:RefreshTooltip(RETAIN_FRAGMENT) end +function ZO_ChapterUpgradePane_Gamepad:GetNarrationText() + local narrations = {} + local selectedData = self:GetSelectedData() + if selectedData then + ZO_AppendNarration(narrations, SCREEN_NARRATION_MANAGER:CreateNarratableObject(selectedData.text)) + + if selectedData.isStandardReward then + ZO_AppendNarration(narrations, SCREEN_NARRATION_MANAGER:CreateNarratableObject(GetString(SI_CHAPTER_UPGRADE_STANDARD_REWARDS_HEADER))) + end + + if selectedData.isCollectorsReward then + ZO_AppendNarration(narrations, SCREEN_NARRATION_MANAGER:CreateNarratableObject(GetString(SI_CHAPTER_UPGRADE_COLLECTORS_REWARDS_HEADER))) + end + end + return narrations +end + -- End ZO_SortFilterList Overrides -- -- Begin ZO_ChapterUpgradePane_Shared Overrides -- @@ -168,6 +186,7 @@ function ZO_ChapterUpgrade_Gamepad:Initialize(control) end EVENT_MANAGER:RegisterForEvent("ZO_ChapterUpgrade_Gamepad", EVENT_REQUEST_SHOW_GAMEPAD_CHAPTER_UPGRADE, OnRequestShowGamepadChapterUpgrade) + EVENT_MANAGER:RegisterForEvent("ZO_ChapterUpgrade_Gamepad", EVENT_COLLECTIBLES_UNLOCK_STATE_CHANGED, function() self:Update() end) self.selectionMode = SELECTION_MODE.CHAPTER diff --git a/esoui/ingame/chatsystem/chatdata.lua b/esoui/ingame/chatsystem/chatdata.lua index 393be1e1d..d90e4dc12 100755 --- a/esoui/ingame/chatsystem/chatdata.lua +++ b/esoui/ingame/chatsystem/chatdata.lua @@ -103,6 +103,13 @@ local MultiLevelEventToCategoryMappings = { [CHAT_CHANNEL_MONSTER_WHISPER] = GetChannelCategoryFromChannel(CHAT_CHANNEL_MONSTER_WHISPER), [CHAT_CHANNEL_MONSTER_EMOTE] = GetChannelCategoryFromChannel(CHAT_CHANNEL_MONSTER_EMOTE), }, + [EVENT_GUILD_KEEP_ATTACK_UPDATE] = { + [CHAT_CHANNEL_GUILD_1] = GetChannelCategoryFromChannel(CHAT_CHANNEL_GUILD_1), + [CHAT_CHANNEL_GUILD_2] = GetChannelCategoryFromChannel(CHAT_CHANNEL_GUILD_2), + [CHAT_CHANNEL_GUILD_3] = GetChannelCategoryFromChannel(CHAT_CHANNEL_GUILD_3), + [CHAT_CHANNEL_GUILD_4] = GetChannelCategoryFromChannel(CHAT_CHANNEL_GUILD_4), + [CHAT_CHANNEL_GUILD_5] = GetChannelCategoryFromChannel(CHAT_CHANNEL_GUILD_5), + }, } for language = OFFICIAL_LANGUAGE_ITERATION_BEGIN, OFFICIAL_LANGUAGE_ITERATION_END do diff --git a/esoui/ingame/chatsystem/chathandlers.lua b/esoui/ingame/chatsystem/chathandlers.lua index 74aade582..dfea263d9 100755 --- a/esoui/ingame/chatsystem/chathandlers.lua +++ b/esoui/ingame/chatsystem/chathandlers.lua @@ -146,7 +146,6 @@ local BUILTIN_MESSAGE_FORMATTERS = { nameToDisplay = ZO_FormatUserFacingDisplayName(displayName) end - ZO_OutputStadiaLog(string.format("ChatHandlers[EVENT_GROUP_INVITE_RESPONSE], ShouldShowGroupErrorInChat(response) = %s", (ShouldShowGroupErrorInChat(response) and "true" or "false"))) if not IsGroupErrorIgnoreResponse(response) and ShouldShowGroupErrorInChat(response) then local alertMessage = nameToDisplay ~= "" and zo_strformat(GetString("SI_GROUPINVITERESPONSE", response), nameToDisplay) or GetString(SI_PLAYER_BUSY) @@ -176,6 +175,27 @@ local BUILTIN_MESSAGE_FORMATTERS = { return GetString(SI_BATTLEGROUND_INACTIVITY_WARNING) end, + [EVENT_GUILD_KEEP_ATTACK_UPDATE] = function(channel, numGuardsKilled, numAttackers, location) + if tonumber(GetSetting(SETTING_TYPE_UI, UI_SETTING_SHOW_AVA_NOTIFICATIONS)) ~= AVA_NOTIFICATIONS_SETTING_CHOICE_DONT_SHOW and + tonumber(GetSetting(SETTING_TYPE_UI, UI_SETTING_SHOW_GUILD_KEEP_NOTICES)) == GUILD_KEEP_NOTICES_SETTING_CHOICE_CHAT then + local channelInfo = ChannelInfo[channel] + + if channelInfo then + local text + if numGuardsKilled > 0 then + text = zo_strformat(SI_GUILD_KEEP_ATTACK_UPDATE, numGuardsKilled, location, numAttackers) + else + text = zo_strformat(SI_GUILD_KEEP_ATTACK_END, location) + end + local channelInfoFormat = GetString(SI_CHAT_MESSAGE_GUILD_NO_SENDER) + local channelLink = CreateChannelLink(channelInfo) + local formattedText = string.format(channelInfoFormat, channelLink, text) + + return formattedText + end + end + end, + ["AddSystemMessage"] = function(messageText) -- system messages will already be formatted by the time they get here return messageText @@ -351,7 +371,7 @@ function ZO_ChatSystem_ShouldUseKeyboardChatSystem() return false end - local useKeyboardChat = GetSetting_Bool(SETTING_TYPE_GAMEPAD, GAMEPAD_SETTING_USE_KEYBOARD_CHAT) and not IsHeronUI() + local useKeyboardChat = GetSetting_Bool(SETTING_TYPE_GAMEPAD, GAMEPAD_SETTING_USE_KEYBOARD_CHAT) return IsInGamepadPreferredMode() == false or useKeyboardChat == true end diff --git a/esoui/ingame/chatsystem/gamepad/chatmenu_gamepad.lua b/esoui/ingame/chatsystem/gamepad/chatmenu_gamepad.lua index 615fd3c65..4e23f7121 100644 --- a/esoui/ingame/chatsystem/gamepad/chatmenu_gamepad.lua +++ b/esoui/ingame/chatsystem/gamepad/chatmenu_gamepad.lua @@ -171,7 +171,17 @@ function ZO_ChatMenu_Gamepad:InitializeFocusKeybinds() local text = self.textEdit:GetText() return text and text ~= "" end, - } + }, + + { + name = GetString(SI_RANDOM_ROLL_KEYBIND), + + keybind = "UI_SHORTCUT_TERTIARY", + + callback = function() + ZO_RandomRollCommand() + end, + }, } ZO_Gamepad_AddBackNavigationKeybindDescriptors(self.textInputAreaKeybindDescriptor, GAME_NAVIGATION_TYPE_BUTTON) self.textInputAreaFocalArea:SetKeybindDescriptor(self.textInputAreaKeybindDescriptor) diff --git a/esoui/ingame/chatsystem/sharedchatsystem.lua b/esoui/ingame/chatsystem/sharedchatsystem.lua index 7260f6966..345f97755 100755 --- a/esoui/ingame/chatsystem/sharedchatsystem.lua +++ b/esoui/ingame/chatsystem/sharedchatsystem.lua @@ -1690,7 +1690,6 @@ function SharedChatSystem:SubmitTextEntry() self.commandPrefixes[prefix](text) else if self:ValidateChatChannel() then - ZO_OutputStadiaLog("SharedChatSystem:SubmitTextEntry, set ZO_Menu_SetLastCommandWasFromMenu == false") ZO_Menu_SetLastCommandWasFromMenu(false) SendChatMessage(text, self.currentChannel, self.currentTarget) end diff --git a/esoui/ingame/collections/collectibledatamanager.lua b/esoui/ingame/collections/collectibledatamanager.lua index 5458a6ccb..c8e54ebc5 100644 --- a/esoui/ingame/collections/collectibledatamanager.lua +++ b/esoui/ingame/collections/collectibledatamanager.lua @@ -10,25 +10,31 @@ ZO_COLLECTION_UPDATE_TYPE = { REBUILD = 1, FORCE_REINITIALIZE = 2, - UNLOCK_STATE_CHANGES = 3, + UNLOCK_STATE_CHANGED = 3, BLACKLIST_CHANGED = 4, + USER_FLAGS_CHANGED = 5, + RANDOM_MOUNT_SETTING_CHANGED = 6, } ---------------------------------- -- Set Default Collectible Data -- ---------------------------------- -ZO_SetDefaultCollectibleData = ZO_InitializingObject:Subclass() +ZO_SetToDefaultCollectibleData = ZO_InitializingObject:Subclass() -function ZO_SetDefaultCollectibleData:Initialize(categoryTypeToSetDefault) +function ZO_SetToDefaultCollectibleData:Initialize(categoryTypeToSetDefault) self.categoryTypeToSetDefault = categoryTypeToSetDefault end -function ZO_SetDefaultCollectibleData:GetCategoryTypeToSetDefault() +function ZO_SetToDefaultCollectibleData:GetCategoryTypeToSetDefault() return self.categoryTypeToSetDefault end -function ZO_SetDefaultCollectibleData:GetName() +function ZO_SetToDefaultCollectibleData:GetCategoryType() + return self:GetCategoryTypeToSetDefault() +end + +function ZO_SetToDefaultCollectibleData:GetName() return ZO_CachedStrFormat(SI_SET_DEFAULT_COLLECTIBLE_NAME_FORMAT, GetString("SI_COLLECTIBLECATEGORYTYPE", self:GetCategoryTypeToSetDefault())) end @@ -38,7 +44,7 @@ do [GAMEPLAY_ACTOR_CATEGORY_COMPANION] = SI_COMPANION_SET_DEFAULT_COLLECTIBLE_DESCRIPTION_FORMAT, } - function ZO_SetDefaultCollectibleData:GetDescription(actorCategory) + function ZO_SetToDefaultCollectibleData:GetDescription(actorCategory) local descriptionFormatter = DESCRIPTION_FORMATTERS[actorCategory] if descriptionFormatter then return ZO_CachedStrFormat(descriptionFormatter, GetString("SI_COLLECTIBLECATEGORYTYPE", self:GetCategoryTypeToSetDefault())) @@ -53,25 +59,176 @@ do [COLLECTIBLE_CATEGORY_TYPE_MOUNT] = "EsoUI/Art/Collections/Default/collections_default_mount.dds", } - function ZO_SetDefaultCollectibleData:GetIcon() + function ZO_SetToDefaultCollectibleData:GetIcon() return COLLECTIBLE_CATEGORY_TYPE_DEFAULT_ICONS[self.categoryTypeToSetDefault] end end -function ZO_SetDefaultCollectibleData:IsActive(actorCategory) +function ZO_SetToDefaultCollectibleData:IsActive(actorCategory) return IsCollectibleCategoryTypeSetToDefault(self.categoryTypeToSetDefault, actorCategory) end -function ZO_SetDefaultCollectibleData:Use(actorCategory) +function ZO_SetToDefaultCollectibleData:IsLocked() + return false +end + +function ZO_SetToDefaultCollectibleData:IsBlocked(actorCategory) + return false +end + +function ZO_SetToDefaultCollectibleData:GetBlockReason(actorCategory) + return "" +end + +function ZO_SetToDefaultCollectibleData:IsUsable(actorCategory) + actorCategory = actorCategory or GAMEPLAY_ACTOR_CATEGORY_PLAYER + return self:IsActiveStateSuppressed(actorCategory) or not self:IsActive(actorCategory) +end + +function ZO_SetToDefaultCollectibleData:Use(actorCategory) + if self:IsActiveStateSuppressed(actorCategory) then + -- If default mount is being suppressed, then using it should just clear the suppression (disable random mount) + if self:GetCategoryType() == COLLECTIBLE_CATEGORY_TYPE_MOUNT then + SetRandomMountType(RANDOM_MOUNT_TYPE_NONE, actorCategory) + end + return + end + SetCollectibleCategoryTypeToDefault(self.categoryTypeToSetDefault, actorCategory) end -function ZO_SetDefaultCollectibleData:GetPrimaryInteractionStringId(actorCategory) +function ZO_SetToDefaultCollectibleData:GetPrimaryInteractionStringId(actorCategory) + -- Function signature mirrors the one on ZO_CollectibleData, + -- but right now there's no support for anything other than Set Active variants + return SI_COLLECTIBLE_ACTION_SET_ACTIVE +end + +function ZO_SetToDefaultCollectibleData:ShouldSuppressActiveState(actorCategory) + return GetRandomMountType(actorCategory) ~= RANDOM_MOUNT_TYPE_NONE +end + +function ZO_SetToDefaultCollectibleData:IsActiveStateSuppressed(actorCategory) + if not self:IsActive(actorCategory) then + return false + end + + return self:ShouldSuppressActiveState(actorCategory) +end + +--------------------------------------- +-- Set Random Mount Collectible Data -- +--------------------------------------- + +ZO_RandomMountCollectibleData = ZO_InitializingObject:Subclass() + +function ZO_RandomMountCollectibleData:Initialize(randomMountType) + self.randomMountType = randomMountType +end + +function ZO_RandomMountCollectibleData:GetRandomMountType() + return self.randomMountType +end + +function ZO_RandomMountCollectibleData:GetCategoryType() + return COLLECTIBLE_CATEGORY_TYPE_MOUNT +end + +function ZO_RandomMountCollectibleData:GetName() + return GetString("SI_RANDOMMOUNTTYPE", self.randomMountType) +end + +function ZO_RandomMountCollectibleData:GetDescription() + return GetString("SI_RANDOMMOUNTTYPE_DESCRIPTION", self.randomMountType) +end + +do + local RANDOM_MOUNT_TYPE_ICONS = + { + [RANDOM_MOUNT_TYPE_FAVORITE] = "EsoUI/Art/Collections/Random_FavoriteMount.dds", + [RANDOM_MOUNT_TYPE_ANY] = "EsoUI/Art/Collections/Random_AnyMount.dds", + } + + function ZO_RandomMountCollectibleData:GetIcon() + return RANDOM_MOUNT_TYPE_ICONS[self.randomMountType] + end +end + +function ZO_RandomMountCollectibleData:IsActive(actorCategory) + return GetRandomMountType(actorCategory) == self.randomMountType +end + +function ZO_RandomMountCollectibleData:IsLocked() + return false +end + +function ZO_RandomMountCollectibleData:IsBlocked(actorCategory) + if self.randomMountType == RANDOM_MOUNT_TYPE_FAVORITE and not ZO_COLLECTIBLE_DATA_MANAGER:HasAnyFavoriteMounts() then + return true + elseif self.randomMountType == RANDOM_MOUNT_TYPE_ANY and not HasAnyUnlockedCollectiblesAvailableToActorCategoryByCategoryType(COLLECTIBLE_CATEGORY_TYPE_MOUNT, actorCategory) then + return true + end + + return false +end + +function ZO_RandomMountCollectibleData:GetBlockReason(actorCategory) + if self.randomMountType == RANDOM_MOUNT_TYPE_FAVORITE and not ZO_COLLECTIBLE_DATA_MANAGER:HasAnyFavoriteMounts() then + return zo_strformat(SI_COLLECTIBLE_REQUIRES_FAVORITE, GetString("SI_COLLECTIBLECATEGORYTYPE", self:GetCategoryType())) + elseif self.randomMountType == RANDOM_MOUNT_TYPE_ANY and not HasAnyUnlockedCollectiblesAvailableToActorCategoryByCategoryType(COLLECTIBLE_CATEGORY_TYPE_MOUNT, actorCategory) then + return zo_strformat(SI_COLLECTIBLE_REQUIRES_UNLOCKED_COLLECTIBLE, GetString("SI_COLLECTIBLECATEGORYTYPE", self:GetCategoryType())) + end + + return "" +end + +function ZO_RandomMountCollectibleData:IsUsable(actorCategory) + return not self:IsActive(actorCategory) +end + +function ZO_RandomMountCollectibleData:Use(actorCategory) + if self:IsBlocked(actorCategory) then + ZO_Alert(UI_ALERT_CATEGORY_ERROR, SOUNDS.GENERAL_ALERT_ERROR, self:GetBlockReason(actorCategory)) + return + end + + SetRandomMountType(self.randomMountType, actorCategory) +end + +function ZO_RandomMountCollectibleData:GetActiveCollectibleText(actorCategory) + if actorCategory == GAMEPLAY_ACTOR_CATEGORY_COMPANION then + return + end + + if not IsMounted() then + return + end + + local activeMountId = GetActiveCollectibleByType(self:GetCategoryType(), actorCategory) + local collectibleData = ZO_COLLECTIBLE_DATA_MANAGER:GetCollectibleDataById(activeMountId) + if collectibleData then + local activeMountName = collectibleData:GetName() + return zo_strformat(SI_COLLECTIBLE_ACTIVE_RANDOM_MOUNT_FORMATTER, ZO_SELECTED_TEXT:Colorize(activeMountName)) + end +end + +function ZO_RandomMountCollectibleData:GetPrimaryInteractionStringId(actorCategory) -- Function signature mirrors the one on ZO_CollectibleData, -- but right now there's no support for anything other than Set Active variants return SI_COLLECTIBLE_ACTION_SET_ACTIVE end +function ZO_RandomMountCollectibleData:ShouldSuppressActiveState(actorCategory) + return false +end + +function ZO_RandomMountCollectibleData:IsActiveStateSuppressed(actorCategory) + if not self:IsActive(actorCategory) then + return false + end + + return self:ShouldSuppressActiveState(actorCategory) +end + ---------------------- -- Collectible Data -- ---------------------- @@ -130,6 +287,11 @@ function ZO_CollectibleData:Refresh() local collectibleId = self.collectibleId local previousUnlockState = self.unlockState self.unlockState = GetCollectibleUnlockStateById(collectibleId) + + local previousUserFlags = self:GetUserFlags() + local newUserFlags = GetCollectibleUserFlags(collectibleId) + self.userFlags = newUserFlags > 0 and newUserFlags or nil + self:SetNew(IsCollectibleNew(collectibleId)) self.cachedNameWithNickname = nil @@ -138,6 +300,8 @@ function ZO_CollectibleData:Refresh() local specializedSortedCollectibles = categoryData:GetSpecializedSortedCollectiblesObject() if previousUnlockState ~= self.unlockState then specializedSortedCollectibles:HandleLockStatusChanged(self) + elseif previousUserFlags ~= newUserFlags then + specializedSortedCollectibles:HandleUserFlagsChanged(self) end end end @@ -227,6 +391,10 @@ function ZO_CollectibleData:IsPurchasable() return IsCollectiblePurchasable(self.collectibleId) end +function ZO_CollectibleData:CanAcquire() + return CanAcquireCollectibleByDefId(self.collectibleId) +end + function ZO_CollectibleData:IsActive(actorCategory) actorCategory = actorCategory or GAMEPLAY_ACTOR_CATEGORY_PLAYER return IsCollectibleActive(self.collectibleId, actorCategory) @@ -236,6 +404,22 @@ function ZO_CollectibleData:IsBlacklisted() return IsCollectibleBlacklisted(self.collectibleId) end +function ZO_CollectibleData:IsFavorite() + return self:IsUserFlagSet(COLLECTIBLE_USER_FLAG_FAVORITE) +end + +function ZO_CollectibleData:IsFavoritable() + return self:IsUnlocked() and IsCollectibleCategoryFavoritable(self:GetCategoryType()) +end + +function ZO_CollectibleData:IsUserFlagSet(userFlag) + return ZO_MaskHasFlag(self:GetUserFlags(), userFlag) +end + +function ZO_CollectibleData:GetUserFlags() + return self.userFlags or 0 +end + function ZO_CollectibleData:GetCategoryType() return GetCollectibleCategoryType(self.collectibleId) end @@ -282,7 +466,11 @@ function ZO_CollectibleData:GetGamepadBackgroundImage() end function ZO_CollectibleData:GetNickname() - return GetCollectibleNickname(self.collectibleId) + return GetCollectibleNickname(self.collectibleId) +end + +function ZO_CollectibleData:GetDefaultNickname() + return GetCollectibleDefaultNickname(self.collectibleId) end function ZO_CollectibleData:GetFormattedNickname() @@ -420,7 +608,7 @@ function ZO_CollectibleData:GetOutfitStyleFreeConversionCollectible() return GetOutfitStyleFreeConversionCollectibleId(self.referenceId) end -function ZO_CollectibleData:IsBlocked() +function ZO_CollectibleData:IsBlocked(actorCategory) return IsCollectibleBlocked(self.collectibleId) end @@ -442,10 +630,18 @@ end function ZO_CollectibleData:IsUsable(actorCategory) actorCategory = actorCategory or GAMEPLAY_ACTOR_CATEGORY_PLAYER - return IsCollectibleUsable(self.collectibleId, actorCategory) + return self:IsActiveStateSuppressed(actorCategory) or IsCollectibleUsable(self.collectibleId, actorCategory) end function ZO_CollectibleData:Use(actorCategory) + if self:IsActiveStateSuppressed(actorCategory) then + -- If the active mount is being suppressed, then using it should just clear the suppression (disable random mount) + if self:IsCategoryType(COLLECTIBLE_CATEGORY_TYPE_MOUNT) then + SetRandomMountType(RANDOM_MOUNT_TYPE_NONE, actorCategory) + end + return + end + -- combination fragment collectibles can consume collectibles on use -- so we want to show a confirmation dialog if it consumes a non-fragment collectible if self:IsCategoryType(COLLECTIBLE_CATEGORY_TYPE_COMBINATION_FRAGMENT) then @@ -474,14 +670,18 @@ end function ZO_CollectibleData:GetPrimaryInteractionStringId(actorCategory) local categoryType = self:GetCategoryType() - if self:IsActive(actorCategory) then + if self:IsActive(actorCategory) and not self:ShouldSuppressActiveState(actorCategory) then if categoryType == COLLECTIBLE_CATEGORY_TYPE_VANITY_PET or categoryType == COLLECTIBLE_CATEGORY_TYPE_ASSISTANT or categoryType == COLLECTIBLE_CATEGORY_TYPE_COMPANION then return SI_COLLECTIBLE_ACTION_DISMISS else return SI_COLLECTIBLE_ACTION_PUT_AWAY end else - if categoryType == COLLECTIBLE_CATEGORY_TYPE_MEMENTO then + if categoryType == COLLECTIBLE_CATEGORY_TYPE_DLC or categoryType == COLLECTIBLE_CATEGORY_TYPE_CHAPTER then + return SI_COLLECTIBLE_ACTION_ACCEPT_QUEST + elseif categoryType == COLLECTIBLE_CATEGORY_TYPE_HOUSE then + return self:IsUnlocked() and SI_HOUSING_BOOK_ACTION_TRAVEL_TO_HOUSE or SI_HOUSING_BOOK_ACTION_PREVIEW_HOUSE + elseif categoryType == COLLECTIBLE_CATEGORY_TYPE_MEMENTO then return SI_COLLECTIBLE_ACTION_USE elseif categoryType == COLLECTIBLE_CATEGORY_TYPE_COMBINATION_FRAGMENT then return SI_COLLECTIBLE_ACTION_COMBINE @@ -493,7 +693,7 @@ function ZO_CollectibleData:GetPrimaryInteractionStringId(actorCategory) return nil else return SI_COLLECTIBLE_ACTION_SET_ACTIVE - end + end else return SI_COLLECTIBLE_ACTION_SET_ACTIVE end @@ -596,6 +796,18 @@ do end end +function ZO_CollectibleData:ShouldSuppressActiveState(actorCategory) + return self:IsCategoryType(COLLECTIBLE_CATEGORY_TYPE_MOUNT) and GetRandomMountType(actorCategory) ~= RANDOM_MOUNT_TYPE_NONE +end + +function ZO_CollectibleData:IsActiveStateSuppressed(actorCategory) + if not self:IsActive(actorCategory) then + return false + end + + return self:ShouldSuppressActiveState(actorCategory) +end + ----------------------------------- -- Specialized Sorted Collectibles ----------------------------------- @@ -639,6 +851,10 @@ function ZO_SpecializedSortedCollectibles:HandlePrimaryResidenceChanged(collecti -- By default, do nothing end +function ZO_SpecializedSortedCollectibles:HandleUserFlagsChanged(collectibleData) + -- By default, do nothing +end + ----------------------------- -- Default Sorted Collectible ----------------------------- @@ -652,7 +868,6 @@ function ZO_DefaultSortedCollectibles:Initialize(owner) self.collectibleNameLookupTable = {} end - function ZO_DefaultSortedCollectibles:InsertCollectible(collectibleData) table.insert(self.sortedCollectibles, collectibleData) @@ -669,10 +884,20 @@ function ZO_DefaultSortedCollectibles:HandleLockStatusChanged(collectibleData) self.dirty = true end +function ZO_DefaultSortedCollectibles:HandleUserFlagsChanged() + self.dirty = true +end + function ZO_DefaultSortedCollectibles:RefreshSort() if self.dirty then local collectibleNameLookupTable = self.collectibleNameLookupTable table.sort(self.sortedCollectibles, function(left, right) + local leftIsFavorite = left:IsFavorite() + local rightIsFavorite = right:IsFavorite() + if leftIsFavorite ~= rightIsFavorite then + return leftIsFavorite + end + local leftIsUnlocked = left:IsUnlocked() local rightIsUnlocked = right:IsUnlocked() if leftIsUnlocked ~= rightIsUnlocked then @@ -853,6 +1078,12 @@ function ZO_SpecializedSortedHouses:RefreshSort() return leftIsPrimaryResidence end + local leftIsFavorite = left:IsFavorite() + local rightIsFavorite = right:IsFavorite() + if leftIsFavorite ~= rightIsFavorite then + return leftIsFavorite + end + local leftIsUnlocked = left:IsUnlocked() local rightIsUnlocked = right:IsUnlocked() if leftIsUnlocked ~= rightIsUnlocked then @@ -1256,7 +1487,7 @@ ZO_CollectibleDataManager = ZO_InitializingCallbackObject:Subclass() function ZO_CollectibleDataManager:Initialize() self.collectibleIdToDataMap = {} self.collectibleCategoryIdToDataMap = {} - self.collectibleCategoryTypeToSetDefaultCollectibleDataMap = {} + self.collectibleCategoryTypeToSetToDefaultCollectibleDataMap = {} ZO_COLLECTIBLE_DATA_MANAGER = self @@ -1286,11 +1517,14 @@ function ZO_CollectibleDataManager:Initialize() EVENT_MANAGER:RegisterForEvent("ZO_CollectibleDataManager", EVENT_ESO_PLUS_FREE_TRIAL_STATUS_CHANGED, function(_, ...) self:OnESOPlusFreeTrialStatusChanged(...) end) EVENT_MANAGER:RegisterForEvent("ZO_CollectibleDataManager", EVENT_COLLECTIBLES_UNLOCK_STATE_CHANGED, function(_, ...) self:OnCollectiblesUnlockStateChanged(...) end) EVENT_MANAGER:RegisterForEvent("ZO_CollectibleDataManager", EVENT_COLLECTIBLE_BLACKLIST_UPDATED, function(_, ...) self:OnCollectibleBlacklistUpdated(...) end) + EVENT_MANAGER:RegisterForEvent("ZO_CollectibleDataManager", EVENT_COLLECTIBLE_USER_FLAGS_UPDATED, function(_, ...) self:OnCollectibleUserFlagsUpdated(...) end) EVENT_MANAGER:RegisterForEvent("ZO_CollectibleDataManager", EVENT_COLLECTIBLE_NEW_STATUS_CLEARED, function(_, ...) self:OnCollectibleNewStatusCleared(...) end) EVENT_MANAGER:RegisterForEvent("ZO_CollectibleDataManager", EVENT_COLLECTIBLE_CATEGORY_NEW_STATUS_CLEARED, function(_, ...) self:OnCollectibleCategoryNewStatusCleared(...) end) EVENT_MANAGER:RegisterForEvent("ZO_CollectibleDataManager", EVENT_COLLECTIBLE_NOTIFICATION_NEW, function(_, ...) self:OnCollectibleNotificationNew(...) end) EVENT_MANAGER:RegisterForEvent("ZO_CollectibleDataManager", EVENT_COLLECTIBLE_NOTIFICATION_REMOVED, function(_, ...) self:OnCollectibleNotificationRemoved(...) end) EVENT_MANAGER:RegisterForEvent("ZO_CollectibleDataManager", EVENT_HOUSING_PRIMARY_RESIDENCE_SET, function(_, ...) self:OnPrimaryResidenceSet(...) end) + EVENT_MANAGER:RegisterForEvent("ZO_CollectibleDataManager", EVENT_RANDOM_MOUNT_SETTING_CHANGED, function(_, ...) self:RandomMountSettingUpdated(...) end) + EVENT_MANAGER:RegisterForEvent("ZO_CollectibleDataManager", EVENT_PLAYER_ACTIVATED, function(_, ...) self:OnPlayerActivated(...) end) self:RebuildCollection() end @@ -1371,7 +1605,7 @@ do ProcessCollectibleDataForUnlockStateChange(collectibleData, collectiblesByNewUnlockState) end - self:FinalizeCollectionUpdates(ZO_COLLECTION_UPDATE_TYPE.UNLOCK_STATE_CHANGES, collectiblesByNewUnlockState) + self:FinalizeCollectionUpdates(ZO_COLLECTION_UPDATE_TYPE.UNLOCK_STATE_CHANGED, collectiblesByNewUnlockState) end local function GetNextDirtyUnlockStateCollectibleIdIter(_, lastCollectibleId) @@ -1394,7 +1628,7 @@ do end end - self:FinalizeCollectionUpdates(ZO_COLLECTION_UPDATE_TYPE.UNLOCK_STATE_CHANGES, collectiblesByNewUnlockState) + self:FinalizeCollectionUpdates(ZO_COLLECTION_UPDATE_TYPE.UNLOCK_STATE_CHANGED, collectiblesByNewUnlockState) end function ZO_CollectibleDataManager:OnCollectibleBlacklistUpdated() @@ -1419,7 +1653,9 @@ function ZO_CollectibleDataManager:FinalizeCollectionUpdates(collectionUpdateTyp end end - if hasUnlockStateChanges or collectionUpdateType ~= ZO_COLLECTION_UPDATE_TYPE.UNLOCK_STATE_CHANGES then + self:ValidateRandomMountSettings() + + if hasUnlockStateChanges or collectionUpdateType ~= ZO_COLLECTION_UPDATE_TYPE.UNLOCK_STATE_CHANGED then self:MapNotifications() self:FireCallbacks("OnCollectionUpdated", collectionUpdateType, collectiblesByNewUnlockState) @@ -1487,6 +1723,45 @@ function ZO_CollectibleDataManager:OnPrimaryResidenceSet(houseId) self:FireCallbacks("PrimaryResidenceSet", houseId) end +function ZO_CollectibleDataManager:OnCollectibleUserFlagsUpdated(collectibleId, oldUserFlags, newUserFlags) + if oldUserFlags ~= newUserFlags then + local collectibleData = self:GetCollectibleDataById(collectibleId) + collectibleData.userFlags = newUserFlags > 0 and newUserFlags or nil -- Memory optimization + local categoryData = collectibleData:GetCategoryData() + if categoryData then + local specializedSortedCollectibles = categoryData:GetSpecializedSortedCollectiblesObject() + specializedSortedCollectibles:HandleUserFlagsChanged(self) + end + + self:ValidateRandomMountSettings() + + self:FireCallbacks("OnCollectibleUserFlagsUpdated", collectibleId) + end +end + +function ZO_CollectibleDataManager:RandomMountSettingUpdated() + local collectiblesByNewUnlockState = {} + self:FinalizeCollectionUpdates(ZO_COLLECTION_UPDATE_TYPE.RANDOM_MOUNT_SETTING_CHANGED, collectiblesByNewUnlockState) +end + +function ZO_CollectibleDataManager:OnPlayerActivated() + self:ValidateRandomMountSettings() +end + +function ZO_CollectibleDataManager:ValidateRandomMountSettings() + local playerRandomMountType = GetRandomMountType(GAMEPLAY_ACTOR_CATEGORY_PLAYER) + if playerRandomMountType ~= RANDOM_MOUNT_TYPE_NONE and not self:HasAnyUnlockedMounts() then + SetRandomMountType(RANDOM_MOUNT_TYPE_NONE, GAMEPLAY_ACTOR_CATEGORY_PLAYER) + elseif playerRandomMountType == RANDOM_MOUNT_TYPE_FAVORITE and not self:HasAnyFavoriteMounts() then + SetRandomMountType(RANDOM_MOUNT_TYPE_ANY, GAMEPLAY_ACTOR_CATEGORY_PLAYER) + end + + local companionRandomMountType = GetRandomMountType(GAMEPLAY_ACTOR_CATEGORY_COMPANION) + if companionRandomMountType ~= RANDOM_MOUNT_TYPE_NONE and not self:HasAnyUnlockedCompanionMounts() then + SetRandomMountType(RANDOM_MOUNT_TYPE_NONE, GAMEPLAY_ACTOR_CATEGORY_COMPANION) + end +end + function ZO_CollectibleDataManager:MapNotifications() for index = 1, GetNumCollectibleNotifications() do local notificationId, collectibleId = GetCollectibleNotificationInfo(index) @@ -1604,13 +1879,25 @@ function ZO_CollectibleDataManager:HasAnyUnlockedCollectibles() return false end -function ZO_CollectibleDataManager:GetSetDefaultCollectibleData(categoryTypeToSetDefault, actorCategory) - local setDefaultCollectibleData = self.collectibleCategoryTypeToSetDefaultCollectibleDataMap[categoryTypeToSetDefault] - if not setDefaultCollectibleData and DoesCollectibleCategoryTypeHaveDefault(categoryTypeToSetDefault, actorCategory) then - setDefaultCollectibleData = ZO_SetDefaultCollectibleData:New(categoryTypeToSetDefault) - self.collectibleCategoryTypeToSetDefaultCollectibleDataMap[categoryTypeToSetDefault] = setDefaultCollectibleData +function ZO_CollectibleDataManager:GetSetToDefaultCollectibleData(categoryTypeToSetDefault, actorCategory) + local setToDefaultCollectibleData = self.collectibleCategoryTypeToSetToDefaultCollectibleDataMap[categoryTypeToSetDefault] + if not setToDefaultCollectibleData and DoesCollectibleCategoryTypeHaveDefault(categoryTypeToSetDefault, actorCategory) then + setToDefaultCollectibleData = ZO_SetToDefaultCollectibleData:New(categoryTypeToSetDefault) + self.collectibleCategoryTypeToSetToDefaultCollectibleDataMap[categoryTypeToSetDefault] = setToDefaultCollectibleData end - return setDefaultCollectibleData + return setToDefaultCollectibleData +end + +function ZO_CollectibleDataManager:HasAnyUnlockedMounts() + return HasAnyUnlockedCollectiblesByCategoryType(COLLECTIBLE_CATEGORY_TYPE_MOUNT) +end + +function ZO_CollectibleDataManager:HasAnyUnlockedCompanionMounts() + return HasAnyUnlockedCollectiblesAvailableToActorCategoryByCategoryType(COLLECTIBLE_CATEGORY_TYPE_MOUNT, GAMEPLAY_ACTOR_CATEGORY_COMPANION) +end + +function ZO_CollectibleDataManager:HasAnyFavoriteMounts() + return DoesCollectibleCategoryContainAnyCollectiblesWithUserFlags(COLLECTIBLE_CATEGORY_TYPE_MOUNT, COLLECTIBLE_USER_FLAG_FAVORITE) end ZO_CollectibleDataManager:New() \ No newline at end of file diff --git a/esoui/ingame/collections/collectionsbook_manager.lua b/esoui/ingame/collections/collectionsbook_manager.lua index 1f52186aa..1e4bd6c9f 100755 --- a/esoui/ingame/collections/collectionsbook_manager.lua +++ b/esoui/ingame/collections/collectionsbook_manager.lua @@ -15,6 +15,7 @@ end function CollectionsBook_Singleton:Initialize() self.ownedHouses = {} + self.primaryResidenceId = GetHousingPrimaryHouse() self.searchString = "" self.searchResults = {} self.searchSpecializationFilters = {} @@ -23,6 +24,7 @@ function CollectionsBook_Singleton:Initialize() EVENT_MANAGER:RegisterForEvent("CollectionsBook_Singleton", EVENT_COLLECTIBLES_SEARCH_RESULTS_READY, function() self:UpdateSearchResults() end) EVENT_MANAGER:RegisterForEvent("CollectionsBook_Singleton", EVENT_COLLECTIBLE_REQUEST_BROWSE_TO, function(eventId, ...) self:BrowseToCollectible(...) end) EVENT_MANAGER:RegisterForEvent("CollectionsBook_Singleton", EVENT_ACTION_UPDATE_COOLDOWNS, function(eventId, ...) self:OnUpdateCooldowns(...) end) + EVENT_MANAGER:RegisterForEvent("CollectionsBook_Singleton", EVENT_HOUSING_PRIMARY_RESIDENCE_SET, function(eventId, ...) self:OnPrimaryResidenceSet(...) end) local function OnCollectionUpdated(collectionUpdateType, collectiblesByNewUnlockState) if collectionUpdateType == ZO_COLLECTION_UPDATE_TYPE.REBUILD then @@ -172,9 +174,28 @@ function CollectionsBook_Singleton:MarkHouseCollectiblePermissionLoadDialogShown end end -function ZO_UpdateCollectibleEntryDataIconVisuals(entryData) +function CollectionsBook_Singleton:OnPrimaryResidenceSet(houseId) + self.primaryResidenceId = houseId + self:FireCallbacks("PrimaryResidenceSet", houseId) +end + +function CollectionsBook_Singleton:GetPrimaryResidence() + return self.primaryResidenceId +end + +function CollectionsBook_Singleton:SetPrimaryResidence(houseId) + if self.primaryResidenceId == 0 then + SetHousingPrimaryHouse(houseId) + elseif houseId ~= self.primaryResidenceId then + local collectibleId = GetCollectibleIdForHouse(self.primaryResidenceId) + local collectibleData = ZO_COLLECTIBLE_DATA_MANAGER:GetCollectibleDataById(collectibleId) + ZO_Dialogs_ShowPlatformDialog("CONFIRM_PRIMARY_RESIDENCE", { currentHouse = houseId }, { mainTextParams = { collectibleData:GetName(), collectibleData:GetNickname()}}) + end +end + +function ZO_UpdateCollectibleEntryDataIconVisuals(entryData, actorCategory) local locked = entryData:IsLocked() - if locked or entryData:IsBlocked() then + if locked or entryData:IsBlocked(actorCategory) then entryData:SetIconDesaturation(1) else entryData:SetIconDesaturation(0) diff --git a/esoui/ingame/collections/gamepad/collectionsbook_gamepad.lua b/esoui/ingame/collections/gamepad/collectionsbook_gamepad.lua index 9b2ad698d..16e1ef695 100755 --- a/esoui/ingame/collections/gamepad/collectionsbook_gamepad.lua +++ b/esoui/ingame/collections/gamepad/collectionsbook_gamepad.lua @@ -83,6 +83,7 @@ function ZO_GamepadCollectionsBook:Initialize(control) ZO_COLLECTIBLE_DATA_MANAGER:RegisterCallback("PrimaryResidenceSet", OnCollectibleUpdated) ZO_COLLECTIBLE_DATA_MANAGER:RegisterCallback("OnCollectibleNewStatusCleared", function(...) self:OnCollectibleNewStatusCleared(...) end) ZO_COLLECTIBLE_DATA_MANAGER:RegisterCallback("OnCollectibleNotificationRemoved", function(...) self:OnCollectibleNotificationRemoved(...) end) + ZO_COLLECTIBLE_DATA_MANAGER:RegisterCallback("OnCollectibleUserFlagsUpdated", function(...) self:OnCollectibleUserFlagsUpdated(...) end) COLLECTIONS_BOOK_SINGLETON:RegisterCallback("OnUpdateCooldowns", function(...) self:OnUpdateCooldowns(...) end) EVENT_MANAGER:RegisterForUpdate("ZO_GamepadCollectionsBook", 250, function() self:UpdateActiveCollectibleCooldownTimer() end) self.control:SetHandler("OnUpdate", function() @@ -147,6 +148,9 @@ function ZO_GamepadCollectionsBook:InitializeUtilityWheel() numSlots = ACTION_BAR_UTILITY_BAR_SIZE, showPendingIcon = true, showCategoryLabel = true, + onSelectionChangedCallback = function() + KEYBIND_STRIP:UpdateKeybindButtonGroup(self.utilityAssignmentKeybindStripDescriptor) + end, customNarrationObjectName = "CollectionsAssignableUtilityWheel", headerNarrationFunction = function() local narrations = {} @@ -233,10 +237,12 @@ function ZO_GamepadCollectionsBook:SetupList(list) local function CollectibleEntrySetup(control, data, selected, reselectingDuringRebuild, enabled, active) local collectibleData = data.dataSource - data:SetNew(collectibleData:IsNew()) - data:SetEnabled(not collectibleData:IsBlocked()) + if collectibleData:IsInstanceOf(ZO_CollectibleData) then + data:InitializeCollectibleVisualData(collectibleData, GAMEPLAY_ACTOR_CATEGORY_PLAYER) + ZO_SetDefaultIconSilhouette(control.icon, collectibleData:IsLocked()) + end + ZO_SharedGamepadEntry_OnSetup(control, data, selected, reselectingDuringRebuild, enabled, active) - ZO_SetDefaultIconSilhouette(control.icon, collectibleData:IsLocked()) end list:AddDataTemplate("ZO_GamepadCollectibleEntryTemplate", CollectibleEntrySetup, ZO_GamepadMenuEntryTemplateParametricListFunction) @@ -269,18 +275,18 @@ function ZO_GamepadCollectionsBook:OnShowing() elseif self.savedOutfitStyleIndex then self:ShowList(self.subcategoryList) self.subcategoryList.list:SetSelectedIndexWithoutAnimation(self.savedOutfitStyleIndex) - elseif self.savedEmoteCollectibleData then - local categoryData = self.savedEmoteCollectibleData:GetCategoryData() + elseif self.savedCollectibleData then + local categoryData = self.savedCollectibleData:GetCategoryData() if categoryData:IsSubcategory() then self:ViewSubcategory(categoryData) else self:ViewCategory(categoryData) end - self:SelectCollectibleEntry(self.savedEmoteCollectibleData:GetId()) + self:SelectCollectibleEntry(self.savedCollectibleData:GetId()) end self.savedOutfitStyleIndex = nil - self.savedEmoteCollectibleData = nil + self.savedCollectibleData = nil end function ZO_GamepadCollectionsBook:OnHiding() @@ -357,6 +363,8 @@ function ZO_GamepadCollectionsBook:InitializeKeybindStripDescriptors() local function ClearPreviewList() self:ClearAllCurrentSlotPreviews() KEYBIND_STRIP:UpdateKeybindButtonGroup(self.subcategoryKeybindStripDescriptor) + --Re-narrate when the previews are cleared + SCREEN_NARRATION_MANAGER:QueueParametricListEntry(self.currentList.list) end local showLockedOption = ZO_RESTYLE_STATION_GAMEPAD:CreateOptionActionDataOutfitStylesShowLocked(RefreshGridList) @@ -424,6 +432,8 @@ function ZO_GamepadCollectionsBook:InitializeKeybindStripDescriptors() local function ClearPreviewGrid() self:ClearAllCurrentSlotPreviews() KEYBIND_STRIP:UpdateKeybindButtonGroup(self.gridKeybindStripDescriptor) + --Re-narrate when the previews are cleared + SCREEN_NARRATION_MANAGER:QueueGridListEntry(self.gridListPanelList) end -- Grid Keybind @@ -478,32 +488,13 @@ function ZO_GamepadCollectionsBook:InitializeKeybindStripDescriptors() { name = function() local collectibleData = self:GetCurrentTargetData() - local nameStringId - if collectibleData:IsStory() then - nameStringId = SI_COLLECTIBLE_ACTION_ACCEPT_QUEST - elseif collectibleData:IsCategoryType(COLLECTIBLE_CATEGORY_TYPE_MEMENTO) then - nameStringId = SI_COLLECTIBLE_ACTION_USE - elseif collectibleData:IsCategoryType(COLLECTIBLE_CATEGORY_TYPE_COMBINATION_FRAGMENT) then - nameStringId = SI_COLLECTIBLE_ACTION_COMBINE - elseif collectibleData:IsHouse() then - nameStringId = collectibleData:IsUnlocked() and SI_HOUSING_BOOK_ACTION_TRAVEL_TO_HOUSE or SI_HOUSING_BOOK_ACTION_PREVIEW_HOUSE - elseif collectibleData:IsCategoryType(COLLECTIBLE_CATEGORY_TYPE_COMPANION) and collectibleData:GetCollectibleAssociatedQuestState() == COLLECTIBLE_ASSOCIATED_QUEST_STATE_INACTIVE then - nameStringId = SI_COLLECTIBLE_ACTION_ACCEPT_QUEST - elseif collectibleData:IsActive(GAMEPLAY_ACTOR_CATEGORY_PLAYER) then - if collectibleData:IsCategoryType(COLLECTIBLE_CATEGORY_TYPE_ASSISTANT) or collectibleData:IsCategoryType(COLLECTIBLE_CATEGORY_TYPE_VANITY_PET) or collectibleData:IsCategoryType(COLLECTIBLE_CATEGORY_TYPE_COMPANION) then - nameStringId = SI_COLLECTIBLE_ACTION_DISMISS - else - nameStringId = SI_COLLECTIBLE_ACTION_PUT_AWAY - end - else - nameStringId = SI_COLLECTIBLE_ACTION_SET_ACTIVE - end + local nameStringId = collectibleData:GetPrimaryInteractionStringId(GAMEPLAY_ACTOR_CATEGORY_PLAYER) return GetString(nameStringId) end, keybind = "UI_SHORTCUT_PRIMARY", callback = function() local collectibleData = self:GetCurrentTargetData() - if collectibleData:IsHouse() then + if collectibleData.IsHouse and collectibleData:IsHouse() then if collectibleData:IsLocked() then -- Preview, behavior will always be inside RequestJumpToHouse(collectibleData:GetReferenceId()) @@ -513,12 +504,14 @@ function ZO_GamepadCollectionsBook:InitializeKeybindStripDescriptors() end else collectibleData:Use(GAMEPLAY_ACTOR_CATEGORY_PLAYER) + --Re-narrate after using the collectible + SCREEN_NARRATION_MANAGER:QueueParametricListEntry(self.currentList.list) end end, visible = function() local collectibleData = self:GetCurrentTargetData() if collectibleData then - if collectibleData:IsHouse() then + if collectibleData.IsHouse and collectibleData:IsHouse() then return true else return collectibleData:IsUsable(GAMEPLAY_ACTOR_CATEGORY_PLAYER) @@ -530,7 +523,10 @@ function ZO_GamepadCollectionsBook:InitializeKeybindStripDescriptors() sound = SOUNDS.DEFAULT_CLICK, enabled = function() local collectibleData = self:GetCurrentTargetData() - if collectibleData:IsHouse() then + if collectibleData:IsInstanceOf(ZO_RandomMountCollectibleData) then + --This is a random mount data entry, not a regular ZO_CollectibleData + return not collectibleData:IsBlocked(GAMEPLAY_ACTOR_CATEGORY_PLAYER), collectibleData:GetBlockReason(GAMEPLAY_ACTOR_CATEGORY_PLAYER) + elseif collectibleData.IsHouse and collectibleData:IsHouse() then local cannotJumpString = collectibleData:IsUnlocked() and GetString(SI_COLLECTIONS_CANNOT_JUMP_TO_HOUSE_FROM_LOCATION) or GetString(SI_COLLECTIONS_CANNOT_PREVIEW_HOUSE_FROM_LOCATION) return CanJumpToHouseFromCurrentLocation(), cannotJumpString else -- IsUsable @@ -539,7 +535,7 @@ function ZO_GamepadCollectionsBook:InitializeKeybindStripDescriptors() return true elseif remainingMs > 0 then return false, GetString(SI_COLLECTIONS_COOLDOWN_ERROR) - elseif collectibleData:IsBlocked() then + elseif collectibleData:IsBlocked(GAMEPLAY_ACTOR_CATEGORY_PLAYER) then local blockReason = GetCollectibleBlockReason(collectibleData:GetId()) return false, zo_strformat(GetString("SI_COLLECTIBLEUSAGEBLOCKREASON", blockReason)) else @@ -575,7 +571,7 @@ function ZO_GamepadCollectionsBook:InitializeKeybindStripDescriptors() } GAMEPAD_PLAYER_EMOTE:QueueBrowseToCategoryData(data) end - self.savedEmoteCollectibleData = collectibleData + self.savedCollectibleData = collectibleData SCENE_MANAGER:Push("gamepad_player_emote") elseif self:CanPurchaseCurrentTarget() then local searchTerm = zo_strformat(SI_CROWN_STORE_SEARCH_FORMAT_STRING, collectibleData:GetName()) @@ -587,7 +583,9 @@ function ZO_GamepadCollectionsBook:InitializeKeybindStripDescriptors() visible = function() local collectibleData = self:GetCurrentTargetData() if collectibleData then - if collectibleData:IsSlottable() then + if not collectibleData:IsInstanceOf(ZO_CollectibleData) then + return false + elseif collectibleData:IsSlottable() then return true elseif collectibleData:IsUnlocked() and collectibleData:IsCategoryType(COLLECTIBLE_CATEGORY_TYPE_EMOTE) then return true @@ -625,10 +623,16 @@ function ZO_GamepadCollectionsBook:InitializeKeybindStripDescriptors() visible = function() local collectibleData = self:GetCurrentTargetData() if collectibleData then - return IsChatSystemAvailableForCurrentPlatform() or collectibleData:IsRenameable() or self:CanPurchaseCurrentTarget() or self:CanUpgradeCurrentTarget() - else - return false + if not collectibleData:IsInstanceOf(ZO_CollectibleData) then + return false + end + + local isHouse = collectibleData:IsHouse() + local isPrimaryResidence = collectibleData:IsPrimaryResidence() + return IsChatSystemAvailableForCurrentPlatform() or collectibleData:IsRenameable() or self:CanPurchaseCurrentTarget() or self:CanUpgradeCurrentTarget() or collectibleData:IsFavoritable() or (isHouse and not isPrimaryResidence) end + + return false end, }, --Subscribe @@ -641,7 +645,15 @@ function ZO_GamepadCollectionsBook:InitializeKeybindStripDescriptors() end, visible = function() local collectibleData = self:GetCurrentTargetData() - return collectibleData and collectibleData:IsStory() and collectibleData:IsUnlockedViaSubscription() and not IsESOPlusSubscriber() + if collectibleData then + if not collectibleData:IsInstanceOf(ZO_CollectibleData) then + return false + else + return collectibleData:IsStory() and collectibleData:IsUnlockedViaSubscription() and not IsESOPlusSubscriber() + end + end + + return false end, }, } @@ -657,6 +669,7 @@ function ZO_GamepadCollectionsBook:InitializeKeybindStripDescriptors() --Utility Wheel Keybinds self.utilityAssignmentKeybindStripDescriptor = {} + local function OnUtilityWheelBack() self:HideAssignableUtilityWheel() end @@ -664,12 +677,19 @@ function ZO_GamepadCollectionsBook:InitializeKeybindStripDescriptors() local function OnAssignPendingData() self.wheel:TryAssignPendingToSelectedEntry() end - ZO_Gamepad_AddForwardNavigationKeybindDescriptors(self.utilityAssignmentKeybindStripDescriptor, GAME_NAVIGATION_TYPE_BUTTON, OnAssignPendingData, GetString(SI_GAMEPAD_ITEM_ACTION_QUICKSLOT_ASSIGN)) + + local function ShouldShowAssignKeybind() + return self.wheel:GetSelectedRadialEntry() ~= nil + end + + ZO_Gamepad_AddForwardNavigationKeybindDescriptors(self.utilityAssignmentKeybindStripDescriptor, GAME_NAVIGATION_TYPE_BUTTON, OnAssignPendingData, GetString(SI_GAMEPAD_ITEM_ACTION_QUICKSLOT_ASSIGN), ShouldShowAssignKeybind) ZO_Gamepad_AddBackNavigationKeybindDescriptors(self.utilityAssignmentKeybindStripDescriptor, GAME_NAVIGATION_TYPE_BUTTON, OnUtilityWheelBack) end function ZO_GamepadCollectionsBook:ShowAssignableUtilityWheel(collectibleData) + local useAccessibleWheel = GetSetting_Bool(SETTING_TYPE_ACCESSIBILITY, ACCESSIBILITY_SETTING_ACCESSIBLE_QUICKWHEELS) + local categoryData = collectibleData:GetCategoryData() local hotbarCategory = GetHotbarForCollectibleCategoryId(categoryData.categoryId) --Determine which wheels we want to show @@ -679,26 +699,34 @@ function ZO_GamepadCollectionsBook:ShowAssignableUtilityWheel(collectibleData) else hotbarCategories = { HOTBAR_CATEGORY_QUICKSLOT_WHEEL } end - self.wheel:SetHotbarCategories(hotbarCategories) - --Disable the current collections list before bringing up the wheel - KEYBIND_STRIP:RemoveKeybindButtonGroup(self.currentList.keybind) - self:DeactivateCurrentList() + --Either show the accessible or regular utility wheel + if useAccessibleWheel then + self.savedCollectibleData = collectibleData + local actionId = collectibleData:GetId() + ACCESSIBLE_ASSIGNABLE_UTILITY_WHEEL_GAMEPAD:SetPendingSimpleAction(ACTION_TYPE_COLLECTIBLE, actionId) + ACCESSIBLE_ASSIGNABLE_UTILITY_WHEEL_GAMEPAD:Show(hotbarCategories) + else + self.wheel:SetHotbarCategories(hotbarCategories) + --Disable the current collections list before bringing up the wheel + KEYBIND_STRIP:RemoveKeybindButtonGroup(self.currentList.keybind) + self:DeactivateCurrentList() - local actionId = collectibleData:GetId() - self.wheel:SetPendingSimpleAction(ACTION_TYPE_COLLECTIBLE, actionId) + local actionId = collectibleData:GetId() + self.wheel:SetPendingSimpleAction(ACTION_TYPE_COLLECTIBLE, actionId) - self.assignLabel:SetHidden(false) - self.selectedCollectibleNameLabel:SetHidden(false) - self.selectedCollectibleNameLabel:SetText(collectibleData:GetFormattedName()) - self.pendingUtilityWheelCollectibleData = collectibleData + self.assignLabel:SetHidden(false) + self.selectedCollectibleNameLabel:SetHidden(false) + self.selectedCollectibleNameLabel:SetText(collectibleData:GetFormattedName()) + self.pendingUtilityWheelCollectibleData = collectibleData - KEYBIND_STRIP:AddKeybindButtonGroup(self.utilityAssignmentKeybindStripDescriptor) + KEYBIND_STRIP:AddKeybindButtonGroup(self.utilityAssignmentKeybindStripDescriptor) - GAMEPAD_TOOLTIPS:ClearTooltip(GAMEPAD_LEFT_TOOLTIP) - GAMEPAD_COLLECTIONS_BOOK_SCENE:AddFragment(GAMEPAD_NAV_QUADRANT_2_3_4_BACKGROUND_FRAGMENT) - -- This will Activate the menu and show it - self.wheel:Show() + GAMEPAD_TOOLTIPS:ClearTooltip(GAMEPAD_LEFT_TOOLTIP) + GAMEPAD_COLLECTIONS_BOOK_SCENE:AddFragment(GAMEPAD_NAV_QUADRANT_2_3_4_BACKGROUND_FRAGMENT) + -- This will Activate the menu and show it + self.wheel:Show() + end end function ZO_GamepadCollectionsBook:HideAssignableUtilityWheel() @@ -815,14 +843,16 @@ function ZO_GamepadCollectionsBook:ShowList(list, dontUpdateTitle) if self:IsViewingCollectionsList() then local collectibleData = self:GetCurrentTargetData() if collectibleData then - self.notificationIdToClear = collectibleData.notificationId - if self.notificationIdToClear or collectibleData:IsNew() then - self.clearNewStatusOnSelectionChanged = true - end + if collectibleData:IsInstanceOf(ZO_CollectibleData) then + self.notificationIdToClear = collectibleData.notificationId + if self.notificationIdToClear or collectibleData:IsNew() then + self.clearNewStatusOnSelectionChanged = true + end - if collectibleData:IsCategoryType(COLLECTIBLE_CATEGORY_TYPE_DLC) then - if IsESOPlusSubscriber() then - TriggerTutorial(TUTORIAL_TRIGGER_COLLECTIONS_DLC_OPENED_AS_SUBSCRIBER) + if collectibleData:IsCategoryType(COLLECTIBLE_CATEGORY_TYPE_DLC) then + if IsESOPlusSubscriber() then + TriggerTutorial(TUTORIAL_TRIGGER_COLLECTIONS_DLC_OPENED_AS_SUBSCRIBER) + end end end end @@ -858,13 +888,17 @@ function ZO_GamepadCollectionsBook:HideCurrentList() self.currentList = nil end -function ZO_GamepadCollectionsBook:OnCollectionUpdated() +function ZO_GamepadCollectionsBook:OnCollectionUpdated(collectionUpdateType) if not self.control:IsHidden() then if self.gridListPanelList and self.gridListPanelList:IsActive() then self:ExitGridList() end - if self.categoryList then + if collectionUpdateType == ZO_COLLECTION_UPDATE_TYPE.RANDOM_MOUNT_SETTING_CHANGED then + -- if random mount changed, we really just want to update the current list just like + -- OnCollectibleUpdated does. + self:OnCollectibleUpdated() + elseif self.categoryList then self:ShowList(self.categoryList) self.categoryList.list:SetSelectedIndex(1) self:BuildCategoryList() @@ -913,6 +947,10 @@ function ZO_GamepadCollectionsBook:OnCollectibleNewStatusCleared(collectibleId) self:OnCollectibleStatusUpdated() end +function ZO_GamepadCollectionsBook:OnCollectibleUserFlagsUpdated(collectibleId) + self:OnCollectibleUpdated(collectibleId) +end + function ZO_GamepadCollectionsBook:BuildCategoryList() self.categoryList.list:Clear() @@ -968,13 +1006,21 @@ function ZO_GamepadCollectionsBook:BuildCollectionList(categoryData, resetSelect collectionList:Clear() collectionListInfo.titleText = nil + local favoriteData = {} local unlockedData = {} local lockedData = {} + self.updateList = {} for _, collectibleData in categoryData:SortedCollectibleIterator({ ZO_CollectibleData.IsShownInCollection }) do local entryData = self:BuildCollectibleData(collectibleData) if collectibleData:IsUnlocked() then - table.insert(unlockedData, entryData) + if collectibleData:IsFavorite() then + table.insert(favoriteData, entryData) + else + table.insert(unlockedData, entryData) + end + + table.insert(self.updateList, entryData) else table.insert(lockedData, entryData) end @@ -982,6 +1028,23 @@ function ZO_GamepadCollectionsBook:BuildCollectionList(categoryData, resetSelect collectionListInfo.titleText = categoryData:GetFormattedName() + if #unlockedData > 0 or #lockedData > 0 then + -- Add Random Selections + local collectibleCategoryTypesInCategory = categoryData:GetCollectibleCategoryTypesInCategory() + if collectibleCategoryTypesInCategory[COLLECTIBLE_CATEGORY_TYPE_MOUNT] then + local setRandomFavoriteMountData = ZO_RandomMountCollectibleData:New(RANDOM_MOUNT_TYPE_FAVORITE) + local randomFavoriteMountEntryData = self:BuildCollectibleCategorySetRandomSelectionData(setRandomFavoriteMountData) + ZO_UpdateCollectibleEntryDataIconVisuals(randomFavoriteMountEntryData, GAMEPLAY_ACTOR_CATEGORY_PLAYER) + collectionList:AddEntry("ZO_GamepadCollectibleEntryTemplate", randomFavoriteMountEntryData) + + local setRandomMountData = ZO_RandomMountCollectibleData:New(RANDOM_MOUNT_TYPE_ANY) + local randomMountEntryData = self:BuildCollectibleCategorySetRandomSelectionData(setRandomMountData) + ZO_UpdateCollectibleEntryDataIconVisuals(randomMountEntryData, GAMEPLAY_ACTOR_CATEGORY_PLAYER) + collectionList:AddEntry("ZO_GamepadCollectibleEntryTemplate", randomMountEntryData) + end + end + + self:BuildListFromTable(collectionList, favoriteData, GetString(SI_COLLECTIONS_FAVORITES_CATEGORY_HEADER)) self:BuildListFromTable(collectionList, unlockedData, GetString("SI_COLLECTIBLEUNLOCKSTATE", COLLECTIBLE_UNLOCK_STATE_UNLOCKED_OWNED)) self:BuildListFromTable(collectionList, lockedData, GetString("SI_COLLECTIBLEUNLOCKSTATE", COLLECTIBLE_UNLOCK_STATE_LOCKED)) @@ -990,19 +1053,30 @@ function ZO_GamepadCollectionsBook:BuildCollectionList(categoryData, resetSelect KEYBIND_STRIP:UpdateKeybindButtonGroup(collectionListInfo.keybind) self.currentCategoryData = categoryData - - self.updateList = unlockedData end function ZO_GamepadCollectionsBook:UpdateCollectionListVisualLayer() local list = self.collectionList.list for i = 1, list:GetNumItems() do - local collectibleData = list:GetDataForDataIndex(i) - collectibleData:SetIsHiddenByWardrobe(collectibleData:IsVisualLayerHidden(GAMEPLAY_ACTOR_CATEGORY_PLAYER)) + local entryData = list:GetDataForDataIndex(i) + + if entryData.IsVisualLayerHidden then + entryData:SetIsHiddenByWardrobe(entryData:IsVisualLayerHidden(GAMEPLAY_ACTOR_CATEGORY_PLAYER)) + end end + self:RefreshRightPanel(self.collectionList.list:GetTargetData()) end +function ZO_GamepadCollectionsBook:BuildCollectibleCategorySetRandomSelectionData(collectibleData) + local entryData = ZO_GamepadEntryData:New(collectibleData:GetName(), collectibleData:GetIcon()) + entryData:SetDataSource(collectibleData) + entryData.actorCategory = GAMEPLAY_ACTOR_CATEGORY_PLAYER + entryData.isEquippedInCurrentCategory = collectibleData:IsActive(GAMEPLAY_ACTOR_CATEGORY_PLAYER) + + return entryData +end + function ZO_GamepadCollectionsBook:BuildCollectibleData(collectibleData) local function GetStoryNarrationText(entryData, entryControl) local narrations = {} @@ -1113,12 +1187,12 @@ function ZO_GamepadCollectionsBook:BuildCollectibleData(collectibleData) entryData.isEquippedInCurrentCategory = collectibleData:IsActive(GAMEPLAY_ACTOR_CATEGORY_PLAYER) entryData.narrationText = GetHouseNarrationText else - entryData.isEquippedInCurrentCategory = collectibleData:IsActive(GAMEPLAY_ACTOR_CATEGORY_PLAYER) + entryData.isEquippedInCurrentCategory = collectibleData:IsActive(GAMEPLAY_ACTOR_CATEGORY_PLAYER) and not collectibleData:ShouldSuppressActiveState(GAMEPLAY_ACTOR_CATEGORY_PLAYER) end entryData:SetIsHiddenByWardrobe(collectibleData:IsVisualLayerHidden(GAMEPLAY_ACTOR_CATEGORY_PLAYER)) - ZO_UpdateCollectibleEntryDataIconVisuals(entryData) + ZO_UpdateCollectibleEntryDataIconVisuals(entryData, GAMEPLAY_ACTOR_CATEGORY_PLAYER) local remainingMs, durationMs = GetCollectibleCooldownAndDuration(collectibleId) if remainingMs > 0 and durationMs > 0 then @@ -1182,7 +1256,9 @@ end function ZO_GamepadCollectionsBook:RefreshRightPanel(entryData) if self:IsViewingCollectionsList() then if entryData then - if entryData:IsStory() then + if entryData.dataSource:IsInstanceOf(ZO_RandomMountCollectibleData) then + self:RefreshRandomMountTooltip(entryData) + elseif entryData:IsStory() then self:RefreshDLCTooltip(entryData) elseif entryData:IsHouse() then self:RefreshHousingTooltip(entryData) @@ -1292,6 +1368,13 @@ function ZO_GamepadCollectionsBook:RefreshHousingTooltip(collectibleData) SCENE_MANAGER:AddFragment(GAMEPAD_COLLECTIONS_BOOK_HOUSING_PANEL_FRAGMENT) end +function ZO_GamepadCollectionsBook:RefreshRandomMountTooltip(collectibleData) + GAMEPAD_TOOLTIPS:ClearTooltip(GAMEPAD_LEFT_TOOLTIP, true) + + GAMEPAD_TOOLTIPS:LayoutImitationCollectibleFromData(GAMEPAD_LEFT_TOOLTIP, collectibleData, GAMEPLAY_ACTOR_CATEGORY_PLAYER) +end + + function ZO_GamepadCollectionsBook:UpdateGridPanelVisibility(categoryData) if categoryData and categoryData:IsOutfitStylesCategory() and categoryData:GetNumCollectibles() > 0 then self:RefreshGridListPanel(categoryData) @@ -1363,6 +1446,8 @@ function ZO_GamepadCollectionsBook:TogglePreviewSelectedOutfitStyle() ApplyChangesToPreviewCollectionShown() end self.gridListPanelList:RefreshGridList() + --Re-narrate when the preview state is toggled + SCREEN_NARRATION_MANAGER:QueueGridListEntry(self.gridListPanelList) end KEYBIND_STRIP:UpdateKeybindButtonGroup(self.gridKeybindStripDescriptor) @@ -1439,7 +1524,7 @@ function ZO_GamepadCollectionsBook:RefreshGridListPanel(categoryData) local function InsertEntryIntoTable(tempTable, data) local entryData = ZO_GridSquareEntryData_Shared:New(data) - ZO_UpdateCollectibleEntryDataIconVisuals(entryData) + ZO_UpdateCollectibleEntryDataIconVisuals(entryData, GAMEPLAY_ACTOR_CATEGORY_PLAYER) table.insert(tempTable, entryData) end @@ -1484,7 +1569,7 @@ end function ZO_GamepadCollectionsBook:CanPurchaseCurrentTarget() if self:IsViewingCollectionsList() then local collectibleData = self:GetCurrentTargetData() - return collectibleData and collectibleData:IsPurchasable() and not collectibleData:IsOwned() and not collectibleData:IsHouse() + return collectibleData and collectibleData:IsPurchasable() and collectibleData:CanAcquire() and not collectibleData:IsHouse() end return false end @@ -1502,7 +1587,6 @@ end ----------------- function ZO_GamepadCollectionsBook:InitializeActionsDialog() - local parametricDialog = ZO_GenericGamepadDialog_GetControl(GAMEPAD_DIALOGS.PARAMETRIC) ZO_Dialogs_RegisterCustomDialog(GAMEPAD_COLLECTIONS_ACTIONS_DIALOG_NAME, { gamepadInfo = @@ -1576,7 +1660,14 @@ function ZO_GamepadCollectionsBook:InitializeActionsDialog() text = GetString(SI_COLLECTIBLE_ACTION_RENAME), setup = ZO_SharedGamepadEntry_OnSetup, callback = function(dialog) - ZO_Dialogs_ShowGamepadDialog(GAMEPAD_COLLECTIONS_RENAME_COLLECTIBLE_DIALOG_NAME, { collectibleId = dialog.data:GetId(), name = dialog.data:GetNickname() }) + local nickname = dialog.data:GetNickname() + local defaultNickname = dialog.data:GetDefaultNickname() + --Only pre-fill the edit text if it's different from the default nickname + local initialEditText = "" + if nickname ~= defaultNickname then + initialEditText = nickname + end + ZO_Dialogs_ShowGamepadDialog(GAMEPAD_COLLECTIONS_RENAME_COLLECTIBLE_DIALOG_NAME, { collectibleId = dialog.data:GetId(), name = initialEditText, defaultName = defaultNickname }) end, visible = function(dialog) return dialog.data:IsRenameable() @@ -1612,13 +1703,43 @@ function ZO_GamepadCollectionsBook:InitializeActionsDialog() end }, }, + -- Add/Remove Favorite + { + template = "ZO_GamepadMenuEntryTemplate", + text = function(dialog) + return dialog.data:IsFavorite() and GetString(SI_COLLECTIBLE_ACTION_REMOVE_FAVORITE) or GetString(SI_COLLECTIBLE_ACTION_ADD_FAVORITE) + end, + templateData = { + setup = ZO_SharedGamepadEntry_OnSetup, + callback = function(dialog) + SetOrClearCollectibleUserFlag(dialog.data:GetId(), COLLECTIBLE_USER_FLAG_FAVORITE, not dialog.data:IsFavorite()) + end, + visible = function(dialog) + return dialog.data:IsFavoritable() + end + }, + }, + -- Set as Primary Residence + { + template = "ZO_GamepadMenuEntryTemplate", + text = GetString(SI_HOUSING_FURNITURE_SETTINGS_GENERAL_PRIMARY_RESIDENCE_BUTTON_TEXT), + templateData = { + setup = ZO_SharedGamepadEntry_OnSetup, + callback = function(dialog) + COLLECTIONS_BOOK_SINGLETON:SetPrimaryResidence(dialog.data:GetReferenceId()) + end, + visible = function(dialog) + return dialog.data:IsHouse() and not dialog.data:IsPrimaryResidence() + end + }, + }, }, buttons = { { keybind = "DIALOG_PRIMARY", text = SI_OK, - callback = function(dialog) + callback = function(dialog) local data = dialog.entryList:GetTargetData() data.callback(dialog) end, @@ -1718,6 +1839,7 @@ function ZO_GamepadCollectionsBook:InitializeRenameCollectibleDialog() if parametricDialog.data then control.editBoxControl:SetText(zo_strformat(SI_COLLECTIBLE_NAME_FORMATTER, parametricDialog.data.name)) + control.editBoxControl:SetDefaultText(zo_strformat(SI_COLLECTIBLE_NAME_FORMATTER, parametricDialog.data.defaultName)) end end, narrationText = ZO_GetDefaultParametricListEditBoxNarrationText, @@ -1732,7 +1854,7 @@ function ZO_GamepadCollectionsBook:InitializeRenameCollectibleDialog() { keybind = "DIALOG_PRIMARY", text = SI_GAMEPAD_SELECT_OPTION, - callback = function(dialog) + callback = function(dialog) local data = dialog.entryList:GetTargetData() SetActiveEdit(data.control.editBoxControl) end, @@ -1740,7 +1862,7 @@ function ZO_GamepadCollectionsBook:InitializeRenameCollectibleDialog() { keybind = "DIALOG_SECONDARY", text = SI_GAMEPAD_COLLECTIONS_SAVE_NAME_OPTION, - callback = function(dialog) + callback = function(dialog) local collectibleId = dialog.data.collectibleId RenameCollectible(collectibleId, inputText) ReleaseDialog() @@ -1750,11 +1872,19 @@ function ZO_GamepadCollectionsBook:InitializeRenameCollectibleDialog() end, clickSound = SOUNDS.DIALOG_ACCEPT, }, + { + keybind = "DIALOG_TERTIARY", + text = SI_COLLECTIONS_INVENTORY_DIALOG_DEFAULT_NAME, + callback = function(dialog) + local data = dialog.entryList:GetTargetData() + data.control.editBoxControl:SetText("") + end, + }, { keybind = "DIALOG_NEGATIVE", text = SI_DIALOG_CANCEL, - callback = function(dialog) + callback = function(dialog) ReleaseDialog() end, }, diff --git a/esoui/ingame/collections/gamepad/collectionsbook_gamepad.xml b/esoui/ingame/collections/gamepad/collectionsbook_gamepad.xml index fae0a8d8d..d40c101e2 100755 --- a/esoui/ingame/collections/gamepad/collectionsbook_gamepad.xml +++ b/esoui/ingame/collections/gamepad/collectionsbook_gamepad.xml @@ -2,11 +2,11 @@ - + - + + + \ No newline at end of file diff --git a/esoui/ingame/crafting/gamepad/gamepadprovisioner.lua b/esoui/ingame/crafting/gamepad/gamepadprovisioner.lua index 11f3fa72e..894d9ab31 100755 --- a/esoui/ingame/crafting/gamepad/gamepadprovisioner.lua +++ b/esoui/ingame/crafting/gamepad/gamepadprovisioner.lua @@ -1,18 +1,25 @@ ZO_GAMEPAD_PROVISIONER_INGREDIENTS_BAR_OFFSET_X = (ZO_GAMEPAD_QUADRANT_1_RIGHT_OFFSET + ZO_GAMEPAD_UI_REFERENCE_WIDTH) / 2 +local GAMEPAD_PROVISIONER_ROOT_SCENE_NAME = "gamepad_provisioner_root" +local GAMEPAD_PROVISIONER_FILLET_SCENE_NAME = "gamepad_provisioner_fillet" +local GAMEPAD_PROVISIONER_CREATION_SCENE_NAME = "gamepad_provisioner_creation" + +PROVISIONER_MODE_ROOT = 0 +PROVISIONER_MODE_FILLET = 1 +PROVISIONER_MODE_CREATION = 2 + local GAMEPAD_PROVISIONER_OPTION_FILTER_INGREDIENTS = 1 local GAMEPAD_PROVISIONER_OPTION_FILTER_SKILLS = 2 local GAMEPAD_PROVISIONER_OPTION_FILTER_QUESTS = 3 - -local optionFilterIngredients = +local optionFilterIngredients = { header = GetString(SI_GAMEPAD_PROVISIONER_OPTIONS), filterName = GetString(SI_PROVISIONER_HAVE_INGREDIENTS), filterTooltip = GetString(SI_CRAFTING_HAVE_INGREDIENTS_TOOLTIP), checked = false, } -local optionFilterSkills = +local optionFilterSkills = { filterName = GetString(SI_PROVISIONER_HAVE_SKILLS), filterTooltip = GetString(SI_CRAFTING_HAVE_SKILLS_TOOLTIP), @@ -27,20 +34,75 @@ local optionFilterQuests = ZO_GamepadProvisioner = ZO_SharedProvisioner:Subclass() -function ZO_GamepadProvisioner:New(...) - return ZO_SharedProvisioner.New(self, ...) -end - -function ZO_GamepadProvisioner:Initialize(control) - self.mainSceneName = "gamepad_provisioner_root" +function ZO_GamepadProvisioner:Initialize(control, scene) + self.mainSceneName = GAMEPAD_PROVISIONER_ROOT_SCENE_NAME ZO_SharedProvisioner.Initialize(self, control) - local skillLineXPBarFragment = ZO_FadeSceneFragment:New(ZO_GamepadProvisionerTopLevelSkillInfo) + self.skillInfoBar = ZO_GamepadProvisionerTopLevelSkillInfo + local skillLineXPBarFragment = ZO_FadeSceneFragment:New(self.skillInfoBar) + local function MakeScene(name, mode) + local scene = self:CreateInteractScene(name) + scene:AddFragment(skillLineXPBarFragment) + scene:RegisterCallback("StateChange", function(oldState, newState) + -- TODO: Determine if any action is needed here + end) + + return scene + end - GAMEPAD_PROVISIONER_ROOT_SCENE = self:CreateInteractScene(self.mainSceneName) + GAMEPAD_PROVISIONER_ROOT_SCENE = MakeScene(GAMEPAD_PROVISIONER_ROOT_SCENE_NAME, PROVISIONER_MODE_ROOT) GAMEPAD_PROVISIONER_ROOT_SCENE:SetInputPreferredMode(INPUT_PREFERRED_MODE_ALWAYS_GAMEPAD) - GAMEPAD_PROVISIONER_ROOT_SCENE:AddFragment(skillLineXPBarFragment) + GAMEPAD_PROVISIONER_FILLET_SCENE = MakeScene(GAMEPAD_PROVISIONER_FILLET_SCENE_NAME, PROVISIONER_MODE_FILLET) + GAMEPAD_PROVISIONER_FILLET_SCENE:SetInputPreferredMode(INPUT_PREFERRED_MODE_ALWAYS_GAMEPAD) + GAMEPAD_PROVISIONER_CREATION_SCENE = MakeScene(GAMEPAD_PROVISIONER_CREATION_SCENE_NAME, PROVISIONER_MODE_CREATION) + GAMEPAD_PROVISIONER_CREATION_SCENE:SetInputPreferredMode(INPUT_PREFERRED_MODE_ALWAYS_GAMEPAD) + GAMEPAD_PROVISIONER_ROOT_SCENE:RegisterCallback("StateChange", function(oldState, newState) + if newState == SCENE_SHOWING then + local craftingType = GetCraftingInteractionType() + + self:RefreshModeList(craftingType) + + self.resetUIs = self.resetUIs or self.oldCraftingType ~= craftingType + + self.filletPanel:SetCraftingType(craftingType, self.oldCraftingType, self.resetUIs) + self.oldCraftingType = craftingType + + self:ResetMode() + if self.resetUIs then + self.modeList:SetSelectedIndexWithoutAnimation(PROVISIONER_MODE_FILLET) + end + + self:SetEnableSkillBar(true) + + self.control:GetNamedChild("IngredientsBar"):SetHidden(true) + self.resultTooltip:SetHidden(true) + + KEYBIND_STRIP:AddKeybindButtonGroup(self.keybindStripDescriptor) + self.modeList.control:SetHidden(false) + self.modeList:Activate() + + local titleString = ZO_GamepadCraftingUtils_GetLineNameForCraftingType(craftingType) + + ZO_GamepadCraftingUtils_SetupGenericHeader(self, titleString) + ZO_GamepadCraftingUtils_RefreshGenericHeader(self) + + local NARRATE_HEADER = true + SCREEN_NARRATION_MANAGER:QueueParametricListEntry(self.modeList, NARRATE_HEADER) + + self.resetUIs = nil + elseif newState == SCENE_HIDDEN then + ZO_InventorySlot_RemoveMouseOverKeybinds() + KEYBIND_STRIP:RemoveKeybindButtonGroup(self.keybindStripDescriptor) + self.modeList:Deactivate() + self.modeList.control:SetHidden(true) + + self:SetEnableSkillBar(false) + end + end) + + GAMEPAD_PROVISIONER_CREATION_SCENE:AddFragment(skillLineXPBarFragment) + GAMEPAD_PROVISIONER_CREATION_SCENE:RegisterCallback("StateChange", function(oldState, newState) if newState == SCENE_SHOWING then ZO_Skills_TieSkillInfoHeaderToCraftingSkill(self.control:GetNamedChild("SkillInfo"), GetCraftingInteractionType()) @@ -48,7 +110,16 @@ function ZO_GamepadProvisioner:Initialize(control) TriggerTutorial(TUTORIAL_TRIGGER_PROVISIONING_OPENED) end + -- Reset provisioning heading within provisioning station + if self.mode == PROVISIONER_MODE_CREATION and self.settings then + self.settings = nil + self:SetDefaultProvisioningSettings() + end + self.control:GetNamedChild("IngredientsBar"):SetHidden(false) + self.resultTooltip:SetHidden(false) + SYSTEMS:GetObject("craftingResults"):SetCraftingTooltip(self.resultTooltip) + self.recipeList.control:SetHidden(false) self.recipeList:Activate() KEYBIND_STRIP:RemoveDefaultExit() @@ -66,12 +137,14 @@ function ZO_GamepadProvisioner:Initialize(control) SYSTEMS:GetObject("craftingResults"):SetCraftingTooltip(nil) ZO_GamepadGenericHeader_Deactivate(self.header) self.recipeList:Deactivate() + self.recipeList.control:SetHidden(true) -- refresh the recipe details passing nil in to appropriately hide/clear the tooltip and ingredient list local NO_RECIPE = nil self:RefreshRecipeDetails(NO_RECIPE) - self.control:GetNamedChild("IngredientsBar"):SetHidden(false) + self.control:GetNamedChild("IngredientsBar"):SetHidden(true) + self.resultTooltip:SetHidden(true) self:EndRecipePreview() @@ -80,6 +153,9 @@ function ZO_GamepadProvisioner:Initialize(control) end end) + local maskControl = control:GetNamedChild("Mask") + self.filletPanel = ZO_FishFillet_Gamepad:New(maskControl:GetNamedChild("Fillet"), control:GetNamedChild("Fillet"), self, GAMEPAD_PROVISIONER_FILLET_SCENE) + self:InitializeSettings() local function OnAddOnLoaded(event, name) @@ -91,20 +167,20 @@ function ZO_GamepadProvisioner:Initialize(control) self.control:RegisterForEvent(EVENT_ADD_ON_LOADED, OnAddOnLoaded) self:InitializeRecipeList() - + self:InitializeModeList() self:InitializeKeybindStripDescriptors() self:InitializeDetails() ZO_GamepadCraftingUtils_InitializeGenericHeader(self, ZO_GAMEPAD_HEADER_TABBAR_CREATE) CALLBACK_MANAGER:RegisterCallback("CraftingAnimationsStarted", function() - if SCENE_MANAGER:IsShowing(self.mainSceneName) then + if SCENE_MANAGER:IsShowing(GAMEPAD_PROVISIONER_CREATION_SCENE_NAME) then self.recipeList:SetActive(false) end end) CALLBACK_MANAGER:RegisterCallback("CraftingAnimationsStopped", function() - if SCENE_MANAGER:IsShowing(self.mainSceneName) then + if SCENE_MANAGER:IsShowing(GAMEPAD_PROVISIONER_CREATION_SCENE_NAME) then self.recipeList:SetActive(true) end end) @@ -144,10 +220,89 @@ function ZO_GamepadProvisioner:InitializeSettings() embeddedSettings.tabs = { furnishingsTab } end +function ZO_GamepadProvisioner:ResetMode() + self.mode = PROVISIONER_MODE_ROOT +end + +function ZO_GamepadProvisioner:SetMode(mode) + if self.mode ~= mode then + self.mode = mode + if mode == PROVISIONER_MODE_CREATION then + SCENE_MANAGER:Push(GAMEPAD_PROVISIONER_CREATION_SCENE_NAME) + else + SCENE_MANAGER:Push(GAMEPAD_PROVISIONER_FILLET_SCENE_NAME) + end + self:UpdateKeybindStrip() + end +end + +function ZO_GamepadProvisioner:SetEnableSkillBar(enable) + if enable then + local craftingType = GetCraftingInteractionType() + ZO_Skills_TieSkillInfoHeaderToCraftingSkill(self.skillInfoBar, craftingType) + else + ZO_Skills_UntieSkillInfoHeaderToCraftingSkill(self.skillInfoBar) + end +end + +function ZO_GamepadProvisioner:UpdateKeybindStrip() + KEYBIND_STRIP:UpdateKeybindButtonGroup(self.keybindStripDescriptor) +end + +function ZO_GamepadProvisioner:AddModeEntry(entry) + self.modeList:AddEntry("ZO_GamepadItemEntryTemplate", entry) +end + +function ZO_GamepadProvisioner:InitializeModeList() + self.modeList = ZO_GamepadVerticalItemParametricScrollList:New(self.control:GetNamedChild("MaskContainerList")) + self.modeList:SetAlignToScreenCenter(true) + self.modeList:AddDataTemplate("ZO_GamepadItemEntryTemplate", ZO_SharedGamepadEntry_OnSetup, ZO_GamepadMenuEntryTemplateParametricListFunction) + + self.filletModeEntry = self:CreateModeEntry(SI_GAMEPAD_PROVISIONING_TAB_FILLET, PROVISIONER_MODE_FILLET, "EsoUI/Art/Crafting/Gamepad/gp_crafting_menuIcon_fillet.dds") + + local narrationInfo = + { + canNarrate = function() + return GAMEPAD_PROVISIONER_ROOT_SCENE:IsShowing() + end, + headerNarrationFunction = function() + return ZO_GamepadGenericHeader_GetNarrationText(self.header, self.headerData) + end, + footerNarrationFunction = function() + local narrations = {} + ZO_AppendNarration(narrations, ZO_WRIT_ADVISOR_GAMEPAD:GetNarrationText()) + return narrations + end, + } + SCREEN_NARRATION_MANAGER:RegisterParametricList(self.modeList, narrationInfo) +end + +function ZO_GamepadProvisioner:CreateModeEntry(name, mode, icon) + local data = ZO_GamepadEntryData:New(GetString(name), icon) + data:SetIconTintOnSelection(true) + data.mode = mode + return data +end + +function ZO_GamepadProvisioner:IsSceneShowing() + return SCENE_MANAGER:IsShowing(GAMEPAD_PROVISIONER_ROOT_SCENE_NAME) or SCENE_MANAGER:IsShowing(GAMEPAD_PROVISIONER_FILLET_SCENE_NAME) or SCENE_MANAGER:IsShowing(GAMEPAD_PROVISIONER_CREATION_SCENE_NAME) +end + +function ZO_GamepadProvisioner:RefreshModeList(craftingType) + self.modeList:Clear() + self:AddModeEntry(self.filletModeEntry) + + local recipeCraftingSystem = GetTradeskillRecipeCraftingSystem(craftingType) + local recipeCraftingSystemNameStringId = _G["SI_RECIPECRAFTINGSYSTEM"..recipeCraftingSystem] + local recipeModeEntry = self:CreateModeEntry(recipeCraftingSystemNameStringId, PROVISIONER_MODE_CREATION, ZO_GetGamepadRecipeCraftingSystemMenuTextures(recipeCraftingSystem)) + self:AddModeEntry(recipeModeEntry) + self.modeList:Commit() +end + function ZO_GamepadProvisioner:ConfigureFromSettings(settings) if self.settings ~= settings then self.settings = settings - + ZO_GamepadCraftingUtils_SetupGenericHeader(self, nil, settings.tabs) ZO_GamepadCraftingUtils_RefreshGenericHeader(self) @@ -157,21 +312,21 @@ end function ZO_GamepadProvisioner:SetDefaultProvisioningSettings() self:ConfigureFromSettings(ZO_GamepadProvisioner.PROVISIONING_SETTINGS) - GAMEPAD_PROVISIONER_ROOT_SCENE:SetInteractionInfo(self.provisionerStationInteraction) + GAMEPAD_PROVISIONER_CREATION_SCENE:SetInteractionInfo(self.provisionerStationInteraction) end function ZO_GamepadProvisioner:EmbedInCraftingScene(interactionInfo) --Set the provisioner interact scenes to have the interaction of the current crafting station so it doesn't terminate the crafting interaction --when we go into the provisioning UI - GAMEPAD_PROVISIONER_ROOT_SCENE:SetInteractionInfo(interactionInfo) - SCENE_MANAGER:Push(self.mainSceneName) + GAMEPAD_PROVISIONER_CREATION_SCENE:SetInteractionInfo(interactionInfo) + SCENE_MANAGER:Push(GAMEPAD_PROVISIONER_CREATION_SCENE_NAME) self:ConfigureFromSettings(ZO_GamepadProvisioner.EMBEDDED_SETTINGS) end function ZO_GamepadProvisioner:InitializeKeybindStripDescriptors() -- back descriptors for screen / options screen - local startButton = + local startButton = { --Ethereal binds show no text, the name field is used to help identify the keybind when debugging. This text does not have to be localized. name = "Gamepad Provisioner Default Exit", @@ -187,14 +342,18 @@ function ZO_GamepadProvisioner:InitializeKeybindStripDescriptors() ethereal = true, } - local backButton = + local backButton = { alignment = KEYBIND_STRIP_ALIGN_LEFT, name = GetString(SI_GAMEPAD_BACK_OPTION), keybind = "UI_SHORTCUT_NEGATIVE", order = -10000, callback = function() - SCENE_MANAGER:HideCurrentScene() + if ITEM_PREVIEW_GAMEPAD:IsInteractionCameraPreviewEnabled() then + self:TogglePreviewMode() + else + SCENE_MANAGER:HideCurrentScene() + end end, visible = function() return not ZO_CraftingUtils_IsPerformingCraftProcess() @@ -286,19 +445,44 @@ function ZO_GamepadProvisioner:InitializeKeybindStripDescriptors() table.insert(self.mainKeybindStripDescriptor, backButton) ZO_CraftingUtils_ConnectKeybindButtonGroupToCraftingProcess(self.mainKeybindStripDescriptor) + + self.keybindStripDescriptor = + { + -- Select mode + { + keybind = "UI_SHORTCUT_PRIMARY", + alignment = KEYBIND_STRIP_ALIGN_LEFT, + + name = function() + return GetString(SI_GAMEPAD_SELECT_OPTION) + end, + + callback = function() + local targetData = self.modeList:GetTargetData() + self:SetMode(targetData.mode) + end, + }, + } + + ZO_Gamepad_AddBackNavigationKeybindDescriptors(self.keybindStripDescriptor, GAME_NAVIGATION_TYPE_BUTTON) + ZO_Gamepad_AddListTriggerKeybindDescriptors(self.keybindStripDescriptor, self.modeList) +end + +function ZO_GamepadProvisioner:OnFilletSlotChanged() + -- Needs to be overridden end function ZO_GamepadProvisioner:ShowOptionsMenu() - local dialogData = + local dialogData = { targetData = self.recipeList:GetTargetData(), - filters = + filters = { [GAMEPAD_PROVISIONER_OPTION_FILTER_INGREDIENTS] = optionFilterIngredients, [GAMEPAD_PROVISIONER_OPTION_FILTER_SKILLS] = optionFilterSkills, [GAMEPAD_PROVISIONER_OPTION_FILTER_QUESTS] = optionFilterQuests, }, - finishedCallback = function() + finishedCallback = function() self:SaveFilters() GAMEPAD_TOOLTIPS:ClearTooltip(GAMEPAD_LEFT_TOOLTIP) end @@ -310,18 +494,18 @@ function ZO_GamepadProvisioner:ShowOptionsMenu() end function ZO_GamepadProvisioner:SetupSavedVars() - local defaults = - { + local defaults = + { haveIngredientsChecked = false, haveSkillsChecked = false, questsOnlyChecked = false, } self.savedVars = ZO_SavedVars:New("ZO_Ingame_SavedVariables", 3, "GamepadProvisioner", defaults) - + optionFilterIngredients.checked = self.savedVars.haveIngredientsChecked optionFilterSkills.checked = self.savedVars.haveSkillsChecked optionFilterQuests.checked = self.savedVars.questsOnlyChecked - + self.control:UnregisterForEvent(EVENT_ADD_ON_LOADED) end @@ -349,10 +533,10 @@ function ZO_GamepadProvisioner:InitializeRecipeList() self:RefreshRecipeDetails(selectedData) end) - local narrationInfo = + local narrationInfo = { canNarrate = function() - return GAMEPAD_PROVISIONER_ROOT_SCENE:IsShowing() + return GAMEPAD_PROVISIONER_CREATION_SCENE:IsShowing() end, headerNarrationFunction = function() return ZO_GamepadGenericHeader_GetNarrationText(self.header, self.headerData) @@ -360,20 +544,24 @@ function ZO_GamepadProvisioner:InitializeRecipeList() footerNarrationFunction = function() local narrations = {} local skillInfoNarration = ZO_Skills_GetSkillInfoHeaderNarrationText(self.control:GetNamedChild("SkillInfo")) - if skillInfoNarration then - ZO_CombineNumericallyIndexedTables(narrations, skillInfoNarration) - end - ZO_CombineNumericallyIndexedTables(narrations, ZO_WRIT_ADVISOR_GAMEPAD:GetNarrationText()) + ZO_AppendNarration(narrations, skillInfoNarration) + ZO_AppendNarration(narrations, ZO_WRIT_ADVISOR_GAMEPAD:GetNarrationText()) return narrations end, } SCREEN_NARRATION_MANAGER:RegisterParametricList(self.recipeList, narrationInfo) ZO_WRIT_ADVISOR_GAMEPAD:RegisterCallback("CycleActiveQuest", function() - if GAMEPAD_PROVISIONER_ROOT_SCENE:IsShowing() then - SCREEN_NARRATION_MANAGER:QueueParametricListEntry(self.recipeList) + if GAMEPAD_PROVISIONER_CREATION_SCENE:IsShowing() then + if self.mode == PROVISIONER_MODE_CREATION or self.settings == ZO_GamepadProvisioner.EMBEDDED_SETTINGS then + SCREEN_NARRATION_MANAGER:QueueParametricListEntry(self.recipeList) + else + SCREEN_NARRATION_MANAGER:QueueParametricListEntry(self.modeList) + end end end) + + self.recipeList.control:SetHidden(true) end function ZO_GamepadProvisioner:SaveFilters() @@ -385,6 +573,7 @@ function ZO_GamepadProvisioner:SaveFilters() self.savedVars.haveSkillsChecked = optionFilterSkills.checked self.savedVars.questsOnlyChecked = optionFilterQuests.checked self:DirtyRecipeList() + ZO_SavePlayerConsoleProfile() end end @@ -408,7 +597,7 @@ function ZO_GamepadProvisioner:InitializeDetails() GAMEPAD_TOOLTIPS:RegisterCustomTooltipNarration(tooltipNarrationInfo) --Narration info for the ingredients for the item we are crafting - local ingredientsNarrationInfo = + local ingredientsNarrationInfo = { canNarrate = function() -- We don't use the visibility of ingredients bar here, as it seems to sometimes rely on the visibility of parent controls. @@ -531,6 +720,8 @@ function ZO_GamepadProvisioner:TogglePreviewMode() ITEM_PREVIEW_GAMEPAD:ToggleInteractionCameraPreview(FRAME_TARGET_CRAFTING_GAMEPAD_FRAGMENT, FRAME_PLAYER_ON_SCENE_HIDDEN_FRAGMENT, GAMEPAD_NAV_QUADRANT_2_3_4_FURNITURE_ITEM_PREVIEW_OPTIONS_FRAGMENT) if ITEM_PREVIEW_GAMEPAD:IsInteractionCameraPreviewEnabled() then self.control:GetNamedChild("IngredientsBar"):SetHidden(true) + elseif self.settings == ZO_GamepadProvisioner.PROVISIONING_SETTINGS and self.mode ~= PROVISIONER_MODE_CREATION then + self.control:GetNamedChild("IngredientsBar"):SetHidden(true) else self.control:GetNamedChild("IngredientsBar"):SetHidden(false) end @@ -540,13 +731,17 @@ end function ZO_GamepadProvisioner:RefreshRecipeDetails(selectedData) if selectedData then - if ITEM_PREVIEW_GAMEPAD:IsInteractionCameraPreviewEnabled() then - if self:CanPreviewRecipe(selectedData) then - self:PreviewRecipe(selectedData) + if self.mode == PROVISIONER_MODE_CREATION or self.settings == ZO_GamepadProvisioner.EMBEDDED_SETTINGS then + if ITEM_PREVIEW_GAMEPAD:IsInteractionCameraPreviewEnabled() then + if self:CanPreviewRecipe(selectedData) then + self:PreviewRecipe(selectedData) + end + self.resultTooltip:SetHidden(true) + else + self.resultTooltip:SetHidden(false) end - self.resultTooltip:SetHidden(true) else - self.resultTooltip:SetHidden(false) + self.resultTooltip:SetHidden(true) end --update recipe tooltip @@ -584,6 +779,11 @@ function ZO_GamepadProvisioner:GetRecipeData() return self.recipeList:GetTargetData() end +--Overridden from base +function ZO_GamepadProvisioner:StartHide() + self:ResetMode() +end + function ZO_GamepadProvisioner_Initialize(control) GAMEPAD_PROVISIONER = ZO_GamepadProvisioner:New(control) end diff --git a/esoui/ingame/crafting/gamepad/gamepadprovisioner.xml b/esoui/ingame/crafting/gamepad/gamepadprovisioner.xml index 517b87517..60d082e8b 100755 --- a/esoui/ingame/crafting/gamepad/gamepadprovisioner.xml +++ b/esoui/ingame/crafting/gamepad/gamepadprovisioner.xml @@ -48,6 +48,21 @@ + + + + + + + + + + + + + + + @@ -77,6 +92,8 @@ + - + - + + + + + + + + + + + + + + + + + - - - - - - - - - + @@ -174,7 +194,7 @@ - + diff --git a/esoui/ingame/crafting/sharedalchemy.lua b/esoui/ingame/crafting/sharedalchemy.lua index 72aa8a175..f947ad1c2 100755 --- a/esoui/ingame/crafting/sharedalchemy.lua +++ b/esoui/ingame/crafting/sharedalchemy.lua @@ -58,12 +58,6 @@ end ZO_SharedAlchemy = ZO_CraftingCreateScreenBase:Subclass() -function ZO_SharedAlchemy:New(...) - local alchemy = ZO_CraftingCreateScreenBase.New(self) - alchemy:Initialize(...) - return alchemy -end - ZO_SharedAlchemy.initializedEvents = false function ZO_SharedAlchemy:Initialize(control) @@ -93,14 +87,7 @@ function ZO_SharedAlchemy:Initialize(control) self:InitializeScenes() - local function OnCraftCompleted() - if not self.control:IsHidden() then - self:UpdateTooltip() - self:UpdateMultiCraft() - end - end - - CALLBACK_MANAGER:RegisterCallback("CraftingAnimationsStopped", OnCraftCompleted) + CALLBACK_MANAGER:RegisterCallback("CraftingAnimationsStopped", function() self:OnCraftCompleted() end) end function ZO_SharedAlchemy:InitializeSharedEvents() @@ -205,6 +192,13 @@ function ZO_SharedAlchemy:UpdateMultiCraft() -- Should be overidden end +function ZO_SharedAlchemy:OnCraftCompleted() + if not self.control:IsHidden() then + self:UpdateTooltip() + self:UpdateMultiCraft() + end +end + function ZO_SharedAlchemy:CanItemBeAddedToCraft(bagId, slotIndex) local usedInCraftingType, craftingSubItemType, rankRequirement = GetItemCraftingInfo(bagId, slotIndex) if usedInCraftingType == CRAFTING_TYPE_ALCHEMY then diff --git a/esoui/ingame/crafting/sharedenchanting.lua b/esoui/ingame/crafting/sharedenchanting.lua index b4a6d8549..5095dc61f 100755 --- a/esoui/ingame/crafting/sharedenchanting.lua +++ b/esoui/ingame/crafting/sharedenchanting.lua @@ -1,11 +1,5 @@ ZO_SharedEnchanting = ZO_CraftingCreateScreenBase:Subclass() -function ZO_SharedEnchanting:New(...) - local enchanting = ZO_CraftingCreateScreenBase.New(self) - enchanting:Initialize(...) - return enchanting -end - ENCHANTING_MODE_NONE = 0 ENCHANTING_MODE_CREATION = 1 ENCHANTING_MODE_EXTRACTION = 2 diff --git a/esoui/ingame/crafting/sharedprovisioner.lua b/esoui/ingame/crafting/sharedprovisioner.lua index 1e7c830ff..39484ff38 100755 --- a/esoui/ingame/crafting/sharedprovisioner.lua +++ b/esoui/ingame/crafting/sharedprovisioner.lua @@ -1,4 +1,3 @@ - -- Returns an array of all versions of this screen local PROVISIONER_SCENE_NAMES = {} @@ -25,12 +24,6 @@ end -- ZO_SharedProvisioner class ZO_SharedProvisioner = ZO_CraftingCreateScreenBase:Subclass() -function ZO_SharedProvisioner:New(...) - local provisioner = ZO_CraftingCreateScreenBase.New(self) - provisioner:Initialize(...) - return provisioner -end - function ZO_SharedProvisioner:Initialize(control) ZO_Provisioner_AddSceneName(self.mainSceneName) @@ -184,15 +177,15 @@ function ZO_SharedProvisioner:DoesRecipePassFilter(specialIngredientType, should if craftingInteractionType ~= requiredCraftingStationType then return false end - + if self.filterType ~= specialIngredientType then return false end - + if shouldRequireIngredients then if maxIterationsForIngredients == 0 then return false - end + end end if shouldRequireSkills then @@ -206,7 +199,7 @@ function ZO_SharedProvisioner:DoesRecipePassFilter(specialIngredientType, should return false end end - + return true end @@ -233,8 +226,8 @@ function ZO_SharedProvisioner:IsCraftable() local recipeData = self:GetRecipeData() if recipeData then return recipeData.maxIterationsForIngredients > 0 - and self:PassesTradeskillLevelReqs(recipeData.tradeskillsLevelReqs) - and self:PassesQualityLevelReq(recipeData.qualityReq) + and self:PassesTradeskillLevelReqs(recipeData.tradeskillsLevelReqs) + and self:PassesQualityLevelReq(recipeData.qualityReq) end return false end diff --git a/esoui/ingame/crafting/smithingcreation_shared.lua b/esoui/ingame/crafting/smithingcreation_shared.lua index 0546fff70..efc5f8d98 100755 --- a/esoui/ingame/crafting/smithingcreation_shared.lua +++ b/esoui/ingame/crafting/smithingcreation_shared.lua @@ -1,11 +1,5 @@ ZO_SharedSmithingCreation = ZO_CraftingCreateScreenBase:Subclass() -function ZO_SharedSmithingCreation:New(...) - local smithingCreation = ZO_CraftingCreateScreenBase.New(self) - smithingCreation:Initialize(...) - return smithingCreation -end - local function GetCurrentCraftingLevel() local craftingType = GetCraftingInteractionType() if craftingType == CRAFTING_TYPE_BLACKSMITHING then diff --git a/esoui/ingame/crowncrates/crowncratespackopening.lua b/esoui/ingame/crowncrates/crowncratespackopening.lua index 9c8cba3e1..3bfb0e369 100644 --- a/esoui/ingame/crowncrates/crowncratespackopening.lua +++ b/esoui/ingame/crowncrates/crowncratespackopening.lua @@ -1154,7 +1154,7 @@ do function ZO_CrownCratesCard:CanActivateCollectible() if self.rewardProductType == MARKET_PRODUCT_TYPE_COLLECTIBLE and not self:IsGemified() then local collectibleData = ZO_COLLECTIBLE_DATA_MANAGER:GetCollectibleDataById(self.rewardReferenceDataId) - if collectibleData:IsUsable(GAMEPLAY_ACTOR_CATEGORY_PLAYER) and collectibleData:IsValidForPlayer() and not collectibleData:IsBlocked() then + if collectibleData:IsUsable(GAMEPLAY_ACTOR_CATEGORY_PLAYER) and collectibleData:IsValidForPlayer() and not collectibleData:IsBlocked(GAMEPLAY_ACTOR_CATEGORY_PLAYER) then return not (collectibleData:IsActive(GAMEPLAY_ACTOR_CATEGORY_PLAYER) or DISALLOWED_EQUIPPABLE_COLLECTIBLE_TYPES[collectibleData:GetCategoryType()]) end end diff --git a/esoui/ingame/fence/gamepad/fencewindowcomponent_gamepad.lua b/esoui/ingame/fence/gamepad/fencewindowcomponent_gamepad.lua index 1ac48dc11..909938304 100755 --- a/esoui/ingame/fence/gamepad/fencewindowcomponent_gamepad.lua +++ b/esoui/ingame/fence/gamepad/fencewindowcomponent_gamepad.lua @@ -1,14 +1,5 @@ - ----------------- ---Initialization ----------------- - ZO_GamepadFenceComponent = ZO_GamepadStoreListComponent:Subclass() -function ZO_GamepadFenceComponent:New(...) - return ZO_GamepadStoreListComponent.New(self, ...) -end - function ZO_GamepadFenceComponent:Initialize(mode, title) ZO_GamepadStoreListComponent.Initialize(self, STORE_WINDOW_GAMEPAD, mode, title) self.mode = mode diff --git a/esoui/ingame/fence/gamepad/fencewindowlaunder_gamepad.lua b/esoui/ingame/fence/gamepad/fencewindowlaunder_gamepad.lua index e1e6fbc1d..2f0d1051e 100755 --- a/esoui/ingame/fence/gamepad/fencewindowlaunder_gamepad.lua +++ b/esoui/ingame/fence/gamepad/fencewindowlaunder_gamepad.lua @@ -1,14 +1,10 @@ ZO_GamepadFenceLaunder = ZO_GamepadFenceComponent:Subclass() -function ZO_GamepadFenceLaunder:New(...) - return ZO_GamepadFenceComponent.New(self, ...) -end - function ZO_GamepadFenceLaunder:Initialize() ZO_GamepadFenceComponent.Initialize(self, ZO_MODE_STORE_LAUNDER, GetString(SI_FENCE_LAUNDER_TAB)) self:InitializeKeybindStrip(GetString(SI_ITEM_ACTION_LAUNDER)) - self:CreateModeData(SI_FENCE_LAUNDER_TAB, self.mode, "EsoUI/Art/Vendor/vendor_tabIcon_fence_up.dds", fragment, self.keybindStripDescriptor) + self:CreateModeData(SI_FENCE_LAUNDER_TAB, self.mode, "EsoUI/Art/Vendor/vendor_tabIcon_fence_up.dds", self.fragment, self.keybindStripDescriptor) self.list:SetNoItemText(GetString(SI_GAMEPAD_NO_STOLEN_ITEMS_LAUNDER)) end diff --git a/esoui/ingame/fence/gamepad/fencewindowsell_gamepad.lua b/esoui/ingame/fence/gamepad/fencewindowsell_gamepad.lua index 285e7423a..fa1f1cfc9 100755 --- a/esoui/ingame/fence/gamepad/fencewindowsell_gamepad.lua +++ b/esoui/ingame/fence/gamepad/fencewindowsell_gamepad.lua @@ -1,14 +1,10 @@ ZO_GamepadFenceSell = ZO_GamepadFenceComponent:Subclass() -function ZO_GamepadFenceSell:New(...) - return ZO_GamepadFenceComponent.New(self, ...) -end - function ZO_GamepadFenceSell:Initialize() ZO_GamepadFenceComponent.Initialize(self, ZO_MODE_STORE_SELL_STOLEN, GetString(SI_STORE_MODE_SELL)) self:InitializeKeybindStrip(GetString(SI_ITEM_ACTION_SELL)) - self:CreateModeData(SI_STORE_MODE_SELL, self.mode, "EsoUI/Art/Vendor/vendor_tabIcon_sell_up.dds", fragment, self.keybindStripDescriptor) + self:CreateModeData(SI_STORE_MODE_SELL, self.mode, "EsoUI/Art/Vendor/vendor_tabIcon_sell_up.dds", self.fragment, self.keybindStripDescriptor) self.list:SetNoItemText(GetString(SI_GAMEPAD_NO_STOLEN_ITEMS_SELL)) end diff --git a/esoui/ingame/fishing/fishing.lua b/esoui/ingame/fishing/fishing.lua index 437fc6589..440c2ca89 100755 --- a/esoui/ingame/fishing/fishing.lua +++ b/esoui/ingame/fishing/fishing.lua @@ -2,6 +2,12 @@ ZO_Fishing = ZO_InteractiveRadialMenuController:Subclass() -- Overridden from base +function ZO_Fishing:Initialize(...) + ZO_InteractiveRadialMenuController.Initialize(self, ...) + self.menu:SetShowKeybinds(function() return ZO_AreTogglableWheelsEnabled() end) + self.menu:SetKeybindActionLayer(GetString(SI_KEYBINDINGS_LAYER_ACCESSIBLE_QUICKWHEEL)) +end + function ZO_Fishing:PrepareForInteraction() if not SCENE_MANAGER:IsInUIMode() then local additionalInfo = select(5, GetGameCameraInteractableActionInfo()) @@ -30,31 +36,4 @@ function ZO_Fishing:PopulateMenu() self.menu:AddEntry(GetString(SI_NO_BAIT_IN_SLOT), "EsoUI/Art/Fishing/bait_emptySlot.dds", "EsoUI/Art/Fishing/bait_emptySlot.dds", nil, i) end end -end - ---Fishing Manager - -local FishingManager = ZO_Object:Subclass() - -function FishingManager:New() - return ZO_Object.New(self) -end - -function FishingManager:StartInteraction() - self.gamepad = IsInGamepadPreferredMode() - if self.gamepad then - return FISHING_GAMEPAD:StartInteraction() - else - return FISHING_KEYBOARD:StartInteraction() - end -end - -function FishingManager:StopInteraction() - if self.gamepad then - return FISHING_GAMEPAD:StopInteraction() - else - return FISHING_KEYBOARD:StopInteraction() - end -end - -FISHING_MANAGER = FishingManager:New() \ No newline at end of file +end \ No newline at end of file diff --git a/esoui/ingame/fishing/gamepad/fishing_gamepad.lua b/esoui/ingame/fishing/gamepad/fishing_gamepad.lua index 43ccd6139..e4e718bc4 100755 --- a/esoui/ingame/fishing/gamepad/fishing_gamepad.lua +++ b/esoui/ingame/fishing/gamepad/fishing_gamepad.lua @@ -1,3 +1,83 @@ +ZO_Fishing_Gamepad = ZO_Fishing:Subclass() + +function ZO_Fishing_Gamepad:Initialize(...) + ZO_Fishing.Initialize(self, ...) + self:InitializeNarrationInfo() +end + +function ZO_Fishing_Gamepad:InitializeNarrationInfo() + local narrationInfo = + { + canNarrate = function() + return self:IsInteracting() + end, + selectedNarrationFunction = function() + local narrations = {} + local selectedEntry = self.menu.selectedEntry + if selectedEntry then + local name = selectedEntry.name + if type(name) == "table" then + name = name[1] + end + ZO_AppendNarration(narrations, SCREEN_NARRATION_MANAGER:CreateNarratableObject(name)) + end + return narrations + end, + headerNarrationFunction = function() + return SCREEN_NARRATION_MANAGER:CreateNarratableObject(GetString(SI_FISHING_WHEEL_NARRATION)) + end, + additionalInputNarrationFunction = function() + local narrationData = {} + if self.menu:ShouldShowKeybinds() then + self.menu:ForEachOrdinalEntry(function(ordinalIndex, entry) + local actionName = ZO_GetRadialMenuActionNameForOrdinalIndex(ordinalIndex) + local name = entry.name + if type(name) == "table" then + name = name[1] + end + + local entryNarrationData = + { + name = name, + keybindName = ZO_Keybindings_GetHighestPriorityNarrationStringFromAction(actionName) or GetString(SI_ACTION_IS_NOT_BOUND), + enabled = true, + } + + table.insert(narrationData, entryNarrationData) + end) + end + + return narrationData + end, + narrationType = NARRATION_TYPE_HUD, + } + SCREEN_NARRATION_MANAGER:RegisterCustomObject("FishingWheelHUD", narrationInfo) +end + +function ZO_Fishing_Gamepad:OnSelectionChangedCallback(selectedEntry) + ZO_Fishing.OnSelectionChangedCallback(self, selectedEntry) + --Re-narrate on selection changed + if selectedEntry then + SCREEN_NARRATION_MANAGER:QueueCustomEntry("FishingWheelHUD") + end +end + +function ZO_Fishing_Gamepad:ShowMenu() + ZO_Fishing.ShowMenu(self) + --Narrate the header when first showing + local NARRATE_HEADER = true + SCREEN_NARRATION_MANAGER:QueueCustomEntry("FishingWheelHUD", NARRATE_HEADER) +end + +function ZO_Fishing_Gamepad:StopInteraction(...) + local wasShowing = ZO_Fishing.StopInteraction(self, ...) + if wasShowing then + --Clear out any in progress HUD narration when exiting the wheel + ClearNarrationQueue(NARRATION_TYPE_HUD) + end + return wasShowing +end + function ZO_Fishing_Gamepad_Initialize(control) - FISHING_GAMEPAD = ZO_Fishing:New(control, "ZO_GamepadSelectableItemRadialMenuEntryTemplate", "DefaultRadialMenuAnimation", "SelectableItemRadialMenuEntryAnimation") + FISHING_GAMEPAD = ZO_Fishing_Gamepad:New(control, "ZO_GamepadSelectableItemRadialMenuEntryTemplate", "DefaultRadialMenuAnimation", "SelectableItemRadialMenuEntryAnimation") end \ No newline at end of file diff --git a/esoui/ingame/globals/bindings.xml b/esoui/ingame/globals/bindings.xml index dabfed8f2..5d40ebf67 100755 --- a/esoui/ingame/globals/bindings.xml +++ b/esoui/ingame/globals/bindings.xml @@ -51,7 +51,7 @@ if not IsBlockActive() then --don't allow Interactions or Jumps while blocking on Gamepad as it will trigger a roll anyway. if interactPromptVisible and not isInactiveClickableFixture then ZO_SetJumpOrInteractDownAction(ZO_JUMP_OR_INTERACT_DID_INTERACT) - if not FISHING_MANAGER:StartInteraction() then GameCameraInteractStart() end + if not INTERACTIVE_WHEEL_MANAGER:StartInteraction(ZO_INTERACTIVE_WHEEL_TYPE_FISHING) then GameCameraInteractStart() end else ZO_SetJumpOrInteractDownAction(ZO_JUMP_OR_INTERACT_DID_JUMP) JumpAscendStart() @@ -61,7 +61,7 @@ local downAction = ZO_GetJumpOrInteractDownAction() if downAction == ZO_JUMP_OR_INTERACT_DID_INTERACT then - if not FISHING_MANAGER:StopInteraction() then GameCameraInteractStart() end + if not INTERACTIVE_WHEEL_MANAGER:HandleUpAction(ZO_INTERACTIVE_WHEEL_TYPE_FISHING) then GameCameraInteractStart() end elseif downAction == ZO_JUMP_OR_INTERACT_DID_JUMP then AscendStop() end @@ -258,9 +258,9 @@ - UTILITY_WHEEL_MANAGER:StartInteraction() + INTERACTIVE_WHEEL_MANAGER:StartInteraction(ZO_INTERACTIVE_WHEEL_TYPE_UTILITY) - if not UTILITY_WHEEL_MANAGER:StopInteraction() then + if not INTERACTIVE_WHEEL_MANAGER:HandleUpAction(ZO_INTERACTIVE_WHEEL_TYPE_UTILITY) then if ZO_ActionBar_CanUseActionSlots() then OnSlotUp(GetCurrentQuickslot(), HOTBAR_CATEGORY_QUICKSLOT_WHEEL) ZO_ActionBar_OnActionButtonUp(GetCurrentQuickslot(), HOTBAR_CATEGORY_QUICKSLOT_WHEEL) @@ -282,10 +282,10 @@ - TARGET_MARKERS:StartInteraction() + INTERACTIVE_WHEEL_MANAGER:StartInteraction(ZO_INTERACTIVE_WHEEL_TYPE_TARGET_MARKER) - if not TARGET_MARKERS:StopInteraction() then + if not INTERACTIVE_WHEEL_MANAGER:HandleUpAction(ZO_INTERACTIVE_WHEEL_TYPE_TARGET_MARKER) then if not HOUSING_EDITOR_SHARED:HandleCycleTarget() then CycleGameCameraPreferredEnemyTarget() end @@ -306,33 +306,34 @@ - TARGET_MARKERS:StartInteraction() - TARGET_MARKERS:StopInteraction() + INTERACTIVE_WHEEL_MANAGER:StartInteraction(ZO_INTERACTIVE_WHEEL_TYPE_TARGET_MARKER) + INTERACTIVE_WHEEL_MANAGER:HandleUpAction(ZO_INTERACTIVE_WHEEL_TYPE_TARGET_MARKER) - - AssignTargetMarkerToReticleTarget(1) - - - AssignTargetMarkerToReticleTarget(2) + + + AssignTargetMarkerToReticleTarget(TARGET_MARKER_TYPE_FOUR) - AssignTargetMarkerToReticleTarget(3) + AssignTargetMarkerToReticleTarget(TARGET_MARKER_TYPE_THREE) - - AssignTargetMarkerToReticleTarget(4) + + AssignTargetMarkerToReticleTarget(TARGET_MARKER_TYPE_TWO) - - AssignTargetMarkerToReticleTarget(5) + + AssignTargetMarkerToReticleTarget(TARGET_MARKER_TYPE_ONE) - - AssignTargetMarkerToReticleTarget(6) + + AssignTargetMarkerToReticleTarget(TARGET_MARKER_TYPE_EIGHT) - AssignTargetMarkerToReticleTarget(7) + AssignTargetMarkerToReticleTarget(TARGET_MARKER_TYPE_SEVEN) - - AssignTargetMarkerToReticleTarget(8) + + AssignTargetMarkerToReticleTarget(TARGET_MARKER_TYPE_SIX) + + + AssignTargetMarkerToReticleTarget(TARGET_MARKER_TYPE_FIVE) @@ -358,13 +359,13 @@ - if not FISHING_MANAGER:StartInteraction() then GameCameraInteractStart() end - if not FISHING_MANAGER:StopInteraction() then GameCameraInteractStart() end + if not INTERACTIVE_WHEEL_MANAGER:StartInteraction(ZO_INTERACTIVE_WHEEL_TYPE_FISHING) then GameCameraInteractStart() end + if not INTERACTIVE_WHEEL_MANAGER:HandleUpAction(ZO_INTERACTIVE_WHEEL_TYPE_FISHING) then GameCameraInteractStart() end PLAYER_TO_PLAYER:StartInteraction() - PLAYER_TO_PLAYER:StopInteraction() + PLAYER_TO_PLAYER:HandleUpAction() @@ -513,6 +514,10 @@ end + + + ClearActiveNarration() + @@ -528,6 +533,7 @@ + @@ -708,6 +714,7 @@ + @@ -735,6 +742,7 @@ + @@ -752,22 +760,215 @@ - if not IsInGamepadPreferredMode() then UTILITY_WHEEL_MANAGER:CycleLeft() end + + if not IsInGamepadPreferredMode() then + return INTERACTIVE_WHEEL_MANAGER:CycleLeft(ZO_INTERACTIVE_WHEEL_TYPE_UTILITY) + end + return false + - if not IsInGamepadPreferredMode() then UTILITY_WHEEL_MANAGER:CycleRight() end + + if not IsInGamepadPreferredMode() then + return INTERACTIVE_WHEEL_MANAGER:CycleRight(ZO_INTERACTIVE_WHEEL_TYPE_UTILITY) + end + return false + - if IsInGamepadPreferredMode() then UTILITY_WHEEL_MANAGER:CycleLeft() end + + if IsInGamepadPreferredMode() then + return INTERACTIVE_WHEEL_MANAGER:CycleLeft(ZO_INTERACTIVE_WHEEL_TYPE_UTILITY) + end + return false + - if IsInGamepadPreferredMode() then UTILITY_WHEEL_MANAGER:CycleRight() end + + if IsInGamepadPreferredMode() then + return INTERACTIVE_WHEEL_MANAGER:CycleRight(ZO_INTERACTIVE_WHEEL_TYPE_UTILITY) + end + return false + + + + + + + + + return INTERACTIVE_WHEEL_MANAGER:HandleHotkeyDownAction(1) + return INTERACTIVE_WHEEL_MANAGER:HandleHotkeyUpAction(1) + + + + return INTERACTIVE_WHEEL_MANAGER:HandleHotkeyDownAction(2) + return INTERACTIVE_WHEEL_MANAGER:HandleHotkeyUpAction(2) + + + + return INTERACTIVE_WHEEL_MANAGER:HandleHotkeyDownAction(3) + return INTERACTIVE_WHEEL_MANAGER:HandleHotkeyUpAction(3) + + + + return INTERACTIVE_WHEEL_MANAGER:HandleHotkeyDownAction(4) + return INTERACTIVE_WHEEL_MANAGER:HandleHotkeyUpAction(4) + + + + return INTERACTIVE_WHEEL_MANAGER:HandleHotkeyDownAction(5) + return INTERACTIVE_WHEEL_MANAGER:HandleHotkeyUpAction(5) + + + + return INTERACTIVE_WHEEL_MANAGER:HandleHotkeyDownAction(6) + return INTERACTIVE_WHEEL_MANAGER:HandleHotkeyUpAction(6) + + + + return INTERACTIVE_WHEEL_MANAGER:HandleHotkeyDownAction(7) + return INTERACTIVE_WHEEL_MANAGER:HandleHotkeyUpAction(7) + + + + return INTERACTIVE_WHEEL_MANAGER:HandleHotkeyDownAction(8) + return INTERACTIVE_WHEEL_MANAGER:HandleHotkeyUpAction(8) + + + return INTERACTIVE_WHEEL_MANAGER:HandleHotkeyDownAction(9) + return INTERACTIVE_WHEEL_MANAGER:HandleHotkeyUpAction(9) + + + + return INTERACTIVE_WHEEL_MANAGER:HandleHotkeyDownAction(10) + return INTERACTIVE_WHEEL_MANAGER:HandleHotkeyUpAction(10) + + + + return INTERACTIVE_WHEEL_MANAGER:CancelCurrentInteraction() + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + return PLAYER_TO_PLAYER:HandleHotkeyDownAction(1) + return PLAYER_TO_PLAYER:HandleHotkeyUpAction(1) + + + + return PLAYER_TO_PLAYER:HandleHotkeyDownAction(2) + return PLAYER_TO_PLAYER:HandleHotkeyUpAction(2) + + + + return PLAYER_TO_PLAYER:HandleHotkeyDownAction(3) + return PLAYER_TO_PLAYER:HandleHotkeyUpAction(3) + + + + return PLAYER_TO_PLAYER:HandleHotkeyDownAction(4) + return PLAYER_TO_PLAYER:HandleHotkeyUpAction(4) + + + + return PLAYER_TO_PLAYER:HandleHotkeyDownAction(5) + return PLAYER_TO_PLAYER:HandleHotkeyUpAction(5) + + + + return PLAYER_TO_PLAYER:HandleHotkeyDownAction(6) + return PLAYER_TO_PLAYER:HandleHotkeyUpAction(6) + + + + return PLAYER_TO_PLAYER:HandleHotkeyDownAction(7) + return PLAYER_TO_PLAYER:HandleHotkeyUpAction(7) + + + + return PLAYER_TO_PLAYER:HandleHotkeyDownAction(8) + return PLAYER_TO_PLAYER:HandleHotkeyUpAction(8) + + + + return PLAYER_TO_PLAYER:HandleHotkeyDownAction(9) + return PLAYER_TO_PLAYER:HandleHotkeyUpAction(9) + + + + return PLAYER_TO_PLAYER:HandleHotkeyDownAction(10) + return PLAYER_TO_PLAYER:HandleHotkeyUpAction(10) + + + + + local CLEAR_SELECTION = true + PLAYER_TO_PLAYER:StopInteraction(CLEAR_SELECTION) + + + + + + + + + + + + + + + + + + + + + + + + + @@ -797,6 +998,52 @@ + + + + + + return ZO_UIErrors_Dismiss() + + + ReloadUI() + + + return ZO_UIErrors_Suppress() + + + return ZO_UIErrors_CopyError() + + + + if IsInGamepadPreferredMode() then + return ZO_UIErrors_ToggleMoreInfo() + else + return false + end + + + + + if IsInGamepadPreferredMode() then + return ZO_UIErrors_PageLeft() + else + return false + end + + + + + if IsInGamepadPreferredMode() then + return ZO_UIErrors_PageRight() + else + return false + end + + + + + @@ -1222,6 +1469,7 @@ + @@ -1284,6 +1532,7 @@ + return ZO_KeybindStrip_HandleKeybindDown(keybind) diff --git a/esoui/ingame/globals/ingamedialogs.lua b/esoui/ingame/globals/ingamedialogs.lua index f5efcdf90..a78384336 100755 --- a/esoui/ingame/globals/ingamedialogs.lua +++ b/esoui/ingame/globals/ingamedialogs.lua @@ -1166,7 +1166,6 @@ ESO_Dialogs["LARGE_GROUP_INVITE_WARNING"] = callback = function(dialog) local characterOrDisplayName = dialog.data GroupInviteByName(characterOrDisplayName) - ZO_OutputStadiaLog("ESO_Dialogs[LARGE_GROUP_INVITE_WARNING], set ZO_Menu_SetLastCommandWasFromMenu == true") ZO_Menu_SetLastCommandWasFromMenu(true) ZO_Alert(ALERT, nil, zo_strformat(GetString("SI_GROUPINVITERESPONSE", GROUP_INVITE_RESPONSE_INVITED), ZO_FormatUserFacingDisplayName(characterOrDisplayName))) end, @@ -2409,7 +2408,14 @@ ESO_Dialogs["LFG_DECLINE_READY_CHECK_CONFIRMATION"] = }, mainText = { - text = SI_LFG_DIALOG_DECLINE_READY_CHECK_CONFIRMATION_BODY, + text = function(dialog) + local INTERACT_TYPE_GROUP_ELECTION = 11 + if dialog.data and dialog.data.incomingType == INTERACT_TYPE_GROUP_ELECTION then + return GetString(SI_LFG_DIALOG_DECLINE_GROUP_ELECTION_READY_CHECK_CONFIRMATION_BODY) + else + return GetString(SI_LFG_DIALOG_DECLINE_READY_CHECK_CONFIRMATION_BODY) + end + end, }, buttons = { @@ -2550,53 +2556,6 @@ ESO_Dialogs["CHAMPION_CONFIRM_CHANGES"] = } } -ESO_Dialogs["COLLECTIONS_INVENTORY_RENAME_COLLECTIBLE"] = -{ - title = - { - text = SI_COLLECTIONS_INVENTORY_DIALOG_RENAME_COLLECTIBLE_TITLE, - }, - mainText = - { - text = SI_COLLECTIONS_INVENTORY_DIALOG_RENAME_COLLECTIBLE_MAIN, - }, - editBox = - { - defaultText = "", - maxInputCharacters = COLLECTIBLE_NAME_MAX_LENGTH, - textType = TEXT_TYPE_ALL, - specialCharacters = {'\'', '-', ' '}, - validatesText = true, - validator = IsValidCollectibleName, - instructions = nil, - selectAll = true, - }, - buttons = - { - [1] = - { - requiresTextInput = true, - text = SI_OK, - noReleaseOnClick = true, - callback = function (dialog) - local inputText = ZO_Dialogs_GetEditBoxText(dialog) - if(inputText and inputText ~= "") then - local violations = {IsValidCollectibleName(inputText)} - if #violations == 0 then - local collectibleId = dialog.data.collectibleId - RenameCollectible(collectibleId, inputText) - ZO_Dialogs_ReleaseDialog("COLLECTIONS_INVENTORY_RENAME_COLLECTIBLE") - end - end - end - }, - [2] = - { - text = SI_DIALOG_CANCEL, - } - } -} - ESO_Dialogs["GAMEPAD_TRAVEL_TO_HOUSE_OPTIONS_DIALOG"] = { gamepadInfo = @@ -2837,7 +2796,7 @@ ESO_Dialogs["HELP_CUSTOMER_SERVICE_SUBMIT_TICKET_ERROR_DIALOG"] = { text = SI_CUSTOMER_SERVICE_OPEN_WEB_BROWSER, visible = function() - return not IsConsoleUI() and not IsHeronUI() + return not IsConsoleUI() end, callback = function(...) ZO_PlatformOpenApprovedURL(APPROVED_URL_ESO_HELP, GetString(SI_CUSTOMER_SERVICE_ESO_HELP_LINK_TEXT), GetString(SI_URL_APPLICATION_WEB)) @@ -4667,7 +4626,6 @@ ESO_Dialogs["GUILD_FINDER_SAVE_FROM_RECRUITMENT_STATUS_UNLISTED"] = }, }, } - ESO_Dialogs["CONFIRM_CLEAR_UNUSED_KEYBINDS"] = { canQueue = true, @@ -4700,3 +4658,50 @@ ESO_Dialogs["CONFIRM_CLEAR_UNUSED_KEYBINDS"] = } }, } + +ESO_Dialogs["CONFIRM_COMPLETE_QUEST_MAX_WARNINGS"] = +{ + canQueue = true, + gamepadInfo = + { + dialogType = GAMEPAD_DIALOGS.BASIC, + }, + + title = + { + text = SI_QUEST_COMPLETE_CONFIRM_TITLE, + }, + + mainText = + { + text = function(dialog) + if dialog.data then + local questName = GetJournalQuestInfo(dialog.data.journalQuestIndex) + local questionText = zo_strformat(SI_QUEST_COMPLETE_CONFIRM_QUESTION, ZO_WHITE:Colorize(questName)) + + local capacityList = ZO_GenerateCommaSeparatedListWithAnd(dialog.data.currenciesWithMaxWarning) + local capacityText = zo_strformat(SI_QUEST_COMPLETE_CONFIRM_CAPACITY, capacityList) + + local acquireList = ZO_GenerateCommaSeparatedListWithAnd(dialog.data.amountsAcquiredWithMaxWarning) + local acquireText = zo_strformat(SI_QUEST_COMPLETE_CONFIRM_ACQUIRE, acquireList) + + return ZO_GenerateParagraphSeparatedList({questionText, ZO_ERROR_COLOR:Colorize(capacityText), ZO_ERROR_COLOR:Colorize(acquireText)}) + end + return "" + end, + }, + + buttons = + { + { + onShowCooldown = 2000, + text = SI_DIALOG_YES, + callback = function(dialog) + CompleteQuest() + end, + }, + { + text = SI_DIALOG_NO, + } + }, +} \ No newline at end of file diff --git a/esoui/ingame/group/gamepad/zo_groupmenu_gamepad.lua b/esoui/ingame/group/gamepad/zo_groupmenu_gamepad.lua index 2f9cd79e1..334979706 100755 --- a/esoui/ingame/group/gamepad/zo_groupmenu_gamepad.lua +++ b/esoui/ingame/group/gamepad/zo_groupmenu_gamepad.lua @@ -223,7 +223,7 @@ function ZO_GroupMenu_Gamepad:UpdateMenuList() list:AddEntry(MENU_ENTRY_TEMPLATE, self.menuEntries[MENU_ENTRY_TYPE_CURRENT_GROUP]) list:AddEntryWithHeader("ZO_GroupMenuGamepadDungeonDifficultyEntry", self.menuEntries[MENU_ENTRY_TYPE_DUNGEON_DIFFICULTY]) - if IsGroupModificationAvailable() and (groupSize == 0 or (playerIsLeader and groupSize < GROUP_SIZE_MAX)) then + if IsGroupModificationAvailable() and (groupSize == 0 or (playerIsLeader and groupSize < MAX_GROUP_SIZE_THRESHOLD)) then table.insert(groupActionEntries, self.menuEntries[MENU_ENTRY_TYPE_INVITE_PLAYER]) local platform = GetUIPlatform() if platform == UI_PLATFORM_XBOX and GetNumberConsoleFriends() > 0 then diff --git a/esoui/ingame/group/grouputils.lua b/esoui/ingame/group/grouputils.lua index 6be709e3e..07b3a4b38 100755 --- a/esoui/ingame/group/grouputils.lua +++ b/esoui/ingame/group/grouputils.lua @@ -9,12 +9,11 @@ local function CompleteGroupInvite(characterOrDisplayName, sentFromChat, display local isLeader = IsUnitGroupLeader("player") local groupSize = GetGroupSize() - if isLeader and groupSize == SMALL_GROUP_SIZE_THRESHOLD then - ZO_Dialogs_ShowPlatformDialog("LARGE_GROUP_INVITE_WARNING", characterOrDisplayName, { mainTextParams = { SMALL_GROUP_SIZE_THRESHOLD } }) + if isLeader and groupSize == STANDARD_GROUP_SIZE_THRESHOLD then + ZO_Dialogs_ShowPlatformDialog("LARGE_GROUP_INVITE_WARNING", characterOrDisplayName, { mainTextParams = { STANDARD_GROUP_SIZE_THRESHOLD } }) else GroupInviteByName(characterOrDisplayName) - ZO_OutputStadiaLog(string.format("GroupUtils:CompleteGroupInvite, set ZO_Menu_SetLastCommandWasFromMenu == %s", not sentFromChat and "true" or "false")) ZO_Menu_SetLastCommandWasFromMenu(not sentFromChat) if displayInvitedMessage then ZO_Alert(ALERT, nil, zo_strformat(GetString("SI_GROUPINVITERESPONSE", GROUP_INVITE_RESPONSE_INVITED), ZO_FormatUserFacingCharacterOrDisplayName(characterOrDisplayName))) diff --git a/esoui/ingame/group/keyboard/zo_groupmenu_keyboard.lua b/esoui/ingame/group/keyboard/zo_groupmenu_keyboard.lua index 8af1921d0..cacecca24 100755 --- a/esoui/ingame/group/keyboard/zo_groupmenu_keyboard.lua +++ b/esoui/ingame/group/keyboard/zo_groupmenu_keyboard.lua @@ -11,6 +11,7 @@ function GroupMenu_Keyboard:Initialize(control) self.control = control self.headerControl = self.control:GetNamedChild("Header") self.categoriesControl = self.control:GetNamedChild("Categories") + self.rolesDividerControl = self.control:GetNamedChild("RolesCategoriesDivider") local function OnStateChange(oldState, newState) if newState == SCENE_SHOWING then @@ -135,7 +136,9 @@ function GroupMenu_Keyboard:InitializeCategories() end local CHILD_SPACING = 0 - self.navigationTree:AddTemplate("ZO_GroupMenuKeyboard_StatusIconHeader", SetupParentNode, nil, nil, ZO_GROUP_MENU_KEYBOARD_TREE_SUBCATEGORY_INDENT, CHILD_SPACING) + local NO_SELECTION_FUNCTION = nil + local NO_EQUALITY_FUNCTION = nil + self.navigationTree:AddTemplate("ZO_GroupMenuKeyboard_StatusIconHeader", SetupParentNode, NO_SELECTION_FUNCTION, NO_EQUALITY_FUNCTION, ZO_GROUP_MENU_KEYBOARD_TREE_SUBCATEGORY_INDENT, CHILD_SPACING) self.navigationTree:AddTemplate("ZO_GroupMenuKeyboard_StatusIconChildlessHeader", SetupNode, OnNodeSelected) self.navigationTree:AddTemplate("ZO_GroupMenuKeyboard_Subcategory", SetupChildNode, OnNodeSelected) self.navigationTree:SetExclusive(true) @@ -157,7 +160,7 @@ function GroupMenu_Keyboard:InitializeKeybindDescriptors() visible = function() local playerIsGrouped, playerIsLeader, groupSize = ZO_ACTIVITY_FINDER_ROOT_MANAGER:GetGroupStatus() - return IsGroupModificationAvailable() and (not playerIsGrouped or (playerIsLeader and groupSize < GROUP_SIZE_MAX)) + return IsGroupModificationAvailable() and (not playerIsGrouped or (playerIsLeader and groupSize < MAX_GROUP_SIZE_THRESHOLD)) end } end @@ -251,7 +254,7 @@ do local nodeTemplate if parentNode then nodeTemplate = "ZO_GroupMenuKeyboard_Subcategory" - elseif nodeData.children then + elseif nodeData.children or (nodeData.getChildrenFunction and #(nodeData.getChildrenFunction()) > 0) then nodeTemplate = "ZO_GroupMenuKeyboard_StatusIconHeader" else nodeTemplate = "ZO_GroupMenuKeyboard_StatusIconChildlessHeader" @@ -264,6 +267,9 @@ do self.categoryFragmentToNodeLookup[nodeData.categoryFragment] = node end end + if nodeData.getChildrenFunction then + node.getChildrenFunction = nodeData.getChildrenFunction + end if nodeData.activityFinderObject then node.control.OnMouseEnter = function(control) self:OnActivityCategoryMouseEnter(control, nodeData) end @@ -280,8 +286,13 @@ do for index, nodeData in ipairs(nodeDataList) do local node = self:AddCategoryTreeNode(nodeData, parentNode) - if nodeData.children then - self:AddCategoryTreeNodes(nodeData.children, node) + local children = nodeData.children + if nodeData.getChildrenFunction then + children = nodeData.getChildrenFunction() + end + + if children then + self:AddCategoryTreeNodes(children, node) end end end @@ -297,6 +308,44 @@ do end end +function GroupMenu_Keyboard:RebuildCategories() + local selectedParentData = nil + local selectedNode = self.navigationTree:GetSelectedNode() + if selectedNode then + local parentNode = selectedNode:GetParent() + if parentNode then + selectedParentData = parentNode:GetData() + end + end + + self.navigationTree:Reset() + ZO_ClearTable(self.categoryFragmentToNodeLookup) + + self:AddCategoryTreeNodes(self.nodeList) + self.navigationTree:Commit() + + if selectedParentData then + local selectNode = self.navigationTree:GetTreeNodeByData(selectedParentData) + if selectNode then + self.navigationTree:SelectFirstChild(selectNode) + end + end +end + +function GroupMenu_Keyboard:HideTree() + self.navigationTree:SetEnabled(false) + self.navigationTree.control:SetHidden(true) + PREFERRED_ROLES.control:SetHidden(true) + self.rolesDividerControl:SetHidden(true) +end + +function GroupMenu_Keyboard:ShowTree() + self.navigationTree:SetEnabled(true) + self.navigationTree.control:SetHidden(false) + PREFERRED_ROLES.control:SetHidden(false) + self.rolesDividerControl:SetHidden(false) +end + function GroupMenu_Keyboard:RefreshCategories() self.navigationTree:RefreshVisible() self.navigationTree:Commit() diff --git a/esoui/ingame/group/zo_grouplist_manager.lua b/esoui/ingame/group/zo_grouplist_manager.lua index 48d7f1159..d25ef990e 100755 --- a/esoui/ingame/group/zo_grouplist_manager.lua +++ b/esoui/ingame/group/zo_grouplist_manager.lua @@ -127,7 +127,7 @@ GROUP_LIST_MANAGER = ZO_GroupList_Manager:New() do local groupUnitTags = setmetatable({}, {__index = function(self, key) local groupIndex = tonumber(key:match("^group(%d+)$")) - if groupIndex and groupIndex >= 1 and groupIndex <= GROUP_SIZE_MAX then + if groupIndex and groupIndex >= 1 and groupIndex <= MAX_GROUP_SIZE_THRESHOLD then self[key] = groupIndex else self[key] = false @@ -149,7 +149,7 @@ do return groupIndices[groupIndex] end - for i = 1, GROUP_SIZE_MAX do + for i = 1, MAX_GROUP_SIZE_THRESHOLD do groupIndices[i] = "group" .. i end end \ No newline at end of file diff --git a/esoui/ingame/guild/gamepad/zo_guildhome_gamepad.lua b/esoui/ingame/guild/gamepad/zo_guildhome_gamepad.lua index d99e13e93..c7660dea3 100755 --- a/esoui/ingame/guild/gamepad/zo_guildhome_gamepad.lua +++ b/esoui/ingame/guild/gamepad/zo_guildhome_gamepad.lua @@ -109,9 +109,20 @@ function ZO_GamepadGuildHome:RefreshHeader(blockTabBarCallbacks) ZO_GamepadGenericHeader_Refresh(self.contentHeader, contentHeaderData) -- list header - self.headerData.messageText = nil; - if(self.currentFragment == GUILD_RANKS_GAMEPAD_FRAGMENT) then + self.headerData.messageText = nil + self.headerData.data1HeaderText = nil + self.headerData.data1Text = nil + self.headerData.data2HeaderText = nil + self.headerData.data2Text = nil + + if self.currentFragment == GUILD_RANKS_GAMEPAD_FRAGMENT then self.headerData.messageText = GUILD_RANKS_GAMEPAD:GetMessageText() + elseif self.currentFragment == GUILD_RECRUITMENT_GAMEPAD_FRAGMENT then + local headerData = GUILD_RECRUITMENT_GAMEPAD:GetHeaderData() + self.headerData.data1HeaderText = headerData.data1HeaderText + self.headerData.data1Text = headerData.data1Text + self.headerData.data2HeaderText = headerData.data2HeaderText + self.headerData.data2Text = headerData.data2Text end ZO_GamepadGenericHeader_Refresh(self.header, self.headerData, blockTabBarCallbacks) diff --git a/esoui/ingame/guild/guildhistory_shared.lua b/esoui/ingame/guild/guildhistory_shared.lua index 91aa67060..3b754218e 100755 --- a/esoui/ingame/guild/guildhistory_shared.lua +++ b/esoui/ingame/guild/guildhistory_shared.lua @@ -30,7 +30,6 @@ GUILD_HISTORY_CATEGORIES = { gamepadIcon = "EsoUI/Art/Guild/gamepad/gp_guild_menuIcon_customization.dds", events = { - [GUILD_EVENT_BANKGOLD_PURCHASE_HERALDRY] = true, [GUILD_EVENT_HERALDRY_EDITED] = true, [GUILD_EVENT_MOTD_EDITED] = true, [GUILD_EVENT_ABOUT_US_EDITED] = true, @@ -80,7 +79,6 @@ GUILD_HISTORY_CATEGORIES = [GUILD_EVENT_BANKITEM_REMOVED] = true, [GUILD_EVENT_BANKGOLD_REMOVED] = true, [GUILD_EVENT_BANKGOLD_KIOSK_BID] = true, - [GUILD_EVENT_BANKGOLD_PURCHASE_HERALDRY] = true, [GUILD_EVENT_GUILD_KIOSK_PURCHASED] = true, [GUILD_EVENT_HERALDRY_EDITED] = true, }, @@ -259,7 +257,6 @@ GUILD_EVENT_EVENT_FORMAT = [GUILD_EVENT_BANKGOLD_KIOSK_BID_REFUND] = KioskRefundEventFormat, -- (eventType, kioskName, goldQuantity) [GUILD_EVENT_BANKGOLD_KIOSK_BID] = KioskBuyOrBidEventFormat, -- (eventType, displayName, goldQuantity, kioskName) [GUILD_EVENT_GUILD_KIOSK_PURCHASED] = KioskBuyOrBidEventFormat, -- (eventType, displayName, goldQuantity, kioskName) - [GUILD_EVENT_BANKGOLD_GUILD_STORE_TAX] = DefaultEventFormatNoParams, -- (eventType) [GUILD_EVENT_MOTD_EDITED] = DefaultEventFormatWithDisplayName, -- (eventType, displayName) [GUILD_EVENT_ABOUT_US_EDITED] = DefaultEventFormatWithDisplayName, -- (eventType, displayName) [GUILD_EVENT_KEEP_CLAIMED] = DefaultEventFormatWithDisplayName, -- (eventType, displayName, keepName, campaignName) diff --git a/esoui/ingame/guild/keyboard/guildhistory_keyboard.lua b/esoui/ingame/guild/keyboard/guildhistory_keyboard.lua index 0d552ef87..7018d43c5 100755 --- a/esoui/ingame/guild/keyboard/guildhistory_keyboard.lua +++ b/esoui/ingame/guild/keyboard/guildhistory_keyboard.lua @@ -1,25 +1,32 @@ -ZO_GUILD_HISTORY_KEYBOARD_CATEGORY_TREE_WIDTH = 240 +ZO_GUILD_HISTORY_KEYBOARD_CATEGORY_TREE_WIDTH = 270 local GUILD_EVENT_DATA = 1 local LOAD_CONTROL_TRIGGER_TIME_S = .5 local GuildHistoryManager = ZO_SortFilterList:Subclass() -function GuildHistoryManager:New(control) - return ZO_SortFilterList.New(self, control) -end - function GuildHistoryManager:Initialize(control) ZO_SortFilterList.Initialize(self, control) - self.noEntriesMessageLabel = GetControl(control, "NoEntriesMessage") - self.control = control - self.loading = GetControl(control, "Loading") + self:SetAlternateRowBackgrounds(true) + self:SetAutomaticallyColorRows(false) + + self.loading = control:GetNamedChild("Loading") self.masterList = {} - - ZO_ScrollList_AddDataType(self.list, GUILD_EVENT_DATA, "ZO_GuildHistoryRow", 60, function(control, data) self:SetupGuildEvent(control, data) end) - self.sortFunction = function(listEntry1, listEntry2) return self:CompareGuildEvents(listEntry1, listEntry2) end + self.scene = ZO_Scene:New("guildHistory", SCENE_MANAGER) + self.scene:RegisterCallback("StateChange", function(oldState, state) + if state == SCENE_SHOWING then + self.refreshGroup:TryClean() + self:RequestInitialEvents() + self:AddKeybinds() + elseif state == SCENE_HIDDEN then + self:RemoveKeybinds() + end + end) + GUILD_HISTORY_SCENE = self.scene + + ZO_ScrollList_AddDataType(self.list, GUILD_EVENT_DATA, "ZO_GuildHistoryRow", 60, function(control, data) self:SetupGuildEvent(control, data) end) self.updateFunction = function(control, timeS) --delay showing the request loading icon by LOAD_CONTROL_TRIGGER_TIME_S @@ -64,21 +71,10 @@ function GuildHistoryManager:Initialize(control) --unwrapping or wrapping at the new size. self.refreshGroup:MarkDirty("EventListData") end) - - GUILD_HISTORY_SCENE = ZO_Scene:New("guildHistory", SCENE_MANAGER) - GUILD_HISTORY_SCENE:RegisterCallback("StateChange", function(oldState, state) - if(state == SCENE_SHOWING) then - self.refreshGroup:TryClean() - self:RequestInitialEvents() - KEYBIND_STRIP:AddKeybindButtonGroup(self.keybindStripDescriptor) - elseif(state == SCENE_HIDDEN) then - KEYBIND_STRIP:RemoveKeybindButtonGroup(self.keybindStripDescriptor) - end - end) end function GuildHistoryManager:InitializeKeybindDescriptors() - self.keybindStripDescriptor = + self:SetKeybindStripDescriptor( { alignment = KEYBIND_STRIP_ALIGN_RIGHT, @@ -95,19 +91,18 @@ function GuildHistoryManager:InitializeKeybindDescriptors() self:RequestMoreEvents() end, }, - } + }) end function GuildHistoryManager:CreateCategoryTree() - self.categoryTree = ZO_Tree:New(GetControl(self.control, "Categories"), 60, -10, ZO_GUILD_HISTORY_KEYBOARD_CATEGORY_TREE_WIDTH) + local TREE_WIDTH = ZO_GUILD_HISTORY_KEYBOARD_CATEGORY_TREE_WIDTH - ZO_SCROLL_BAR_WIDTH + self.categoryTree = ZO_Tree:New(self.control:GetNamedChild("Categories"), 60, -10, TREE_WIDTH) --Category Header + local TEXT_LABEL_MAX_WIDTH = TREE_WIDTH - ZO_TREE_ENTRY_ICON_HEADER_TEXT_OFFSET_X local function CategoryHeaderSetup(node, control, categoryId, open) - -- 62 is the amount of space from the left side of the parent control to the right side of the text label - -- 25 is the offset from the icon to the text label - local textLabelMaxWidth = ZO_GUILD_HISTORY_KEYBOARD_CATEGORY_TREE_WIDTH - 62 - 25 - control.text:SetDimensionConstraints(0, 0, textLabelMaxWidth, 0) + control.text:SetDimensionConstraints(0, 0, TEXT_LABEL_MAX_WIDTH, 0) control.text:SetModifyTextType(MODIFY_TEXT_TYPE_UPPERCASE) control.text:SetText(GetString("SI_GUILDHISTORYCATEGORY", categoryId)) @@ -142,6 +137,8 @@ function GuildHistoryManager:CreateCategoryTree() self.selectedCategory = data.categoryId self.selectedSubcategory = data.subcategoryId + self:SetEmptyText(ZO_GuildHistory_GetNoEntriesText(self.selectedCategory, self.selectedSubcategory, self.guildId)) + --if it's the same category we can just mess with the filter instead of rebuilding the whole list if oldSelectedCategory == self.selectedCategory then self.refreshGroup:MarkDirty("EventListFilters") @@ -150,7 +147,7 @@ function GuildHistoryManager:CreateCategoryTree() self.refreshGroup:MarkDirty("EventListData") end ZO_ScrollList_ResetToTop(self.list) - KEYBIND_STRIP:UpdateKeybindButtonGroup(self.keybindStripDescriptor) + self:UpdateKeybinds() end end @@ -182,57 +179,57 @@ function GuildHistoryManager:SetGuildId(guildId) self.guildId = guildId self:RequestInitialEvents() self.refreshGroup:MarkDirty("EventListData") - KEYBIND_STRIP:UpdateKeybindButtonGroup(self.keybindStripDescriptor) + self:UpdateKeybinds() end function GuildHistoryManager:SetupGuildEvent(control, data) - local bg = GetControl(control, "BG") - local hidden = data.sortIndex and (data.sortIndex % 2) == 0 - bg:SetHidden(hidden) + ZO_SortFilterList.SetupRowBG(self, control, data) local description = self:FormatEvent(data.eventType, data.param1, data.param2, data.param3, data.param4, data.param5, data.param6) local formattedTime = ZO_FormatDurationAgo(data.secsSinceEvent + GetGameTimeSeconds() - self.lastEventDataUpdateS) - GetControl(control, "Description"):SetText(description) - GetControl(control, "Time"):SetText(formattedTime) + control.descriptionLabel:SetText(description) + control.timeLabel:SetText(formattedTime) end function GuildHistoryManager:IsShowing() - return GUILD_HISTORY_SCENE and GUILD_HISTORY_SCENE:IsShowing() + return self.scene:IsShowing() end function GuildHistoryManager:FormatEvent(eventType, ...) local format = GUILD_EVENT_EVENT_FORMAT[eventType] - if(format) then + if format then return format(eventType, ...) end end -function GuildHistoryManager:ShouldShowEventType(eventType) - return GUILD_EVENT_EVENT_FORMAT[eventType] ~= nil -end +do + local function ShouldShowEventType(eventType) + return GUILD_EVENT_EVENT_FORMAT[eventType] ~= nil + end -function GuildHistoryManager:BuildMasterList() - if self.guildId and self.selectedCategory then - ZO_ClearNumericallyIndexedTable(self.masterList) - self.lastEventDataUpdateS = GetFrameTimeSeconds() - for i = 1, GetNumGuildEvents(self.guildId, self.selectedCategory) do - local eventType, secsSinceEvent, param1, param2, param3, param4, param5, param6, eventId = GetGuildEventInfo(self.guildId, self.selectedCategory, i) - if self:ShouldShowEventType(eventType) then - local event = - { - eventId = eventId, - eventType = eventType, - param1 = param1, - param2 = param2, - param3 = param3, - param4 = param4, - param5 = param5, - param6 = param6, - secsSinceEvent = secsSinceEvent, - subcategoryId = ComputeGuildHistoryEventSubcategory(eventType, self.selectedCategory), - } - table.insert(self.masterList, event) + function GuildHistoryManager:BuildMasterList() + if self.guildId and self.selectedCategory then + ZO_ClearNumericallyIndexedTable(self.masterList) + self.lastEventDataUpdateS = GetFrameTimeSeconds() + for i = 1, GetNumGuildEvents(self.guildId, self.selectedCategory) do + local eventType, secsSinceEvent, param1, param2, param3, param4, param5, param6, eventId = GetGuildEventInfo(self.guildId, self.selectedCategory, i) + if ShouldShowEventType(eventType) then + local event = + { + eventId = eventId, + eventType = eventType, + param1 = param1, + param2 = param2, + param3 = param3, + param4 = param4, + param5 = param5, + param6 = param6, + secsSinceEvent = secsSinceEvent, + subcategoryId = ComputeGuildHistoryEventSubcategory(eventType, self.selectedCategory), + } + table.insert(self.masterList, event) + end end end end @@ -240,31 +237,25 @@ end function GuildHistoryManager:FilterScrollList() local scrollData = ZO_ScrollList_GetDataList(self.list) - local listWidth = self.list:GetNamedChild("Contents"):GetWidth() - ZO_ClearNumericallyIndexedTable(scrollData) - for i = 1, #self.masterList do - local data = self.masterList[i] + + for i, data in ipairs(self.masterList) do if self.selectedSubcategory == nil or self.selectedSubcategory == data.subcategoryId then table.insert(scrollData, ZO_ScrollList_CreateDataEntry(GUILD_EVENT_DATA, data)) end end - - local hasEntries = #scrollData > 0 - self.noEntriesMessageLabel:SetHidden(hasEntries) - if not hasEntries then - self.noEntriesMessageLabel:SetText(ZO_GuildHistory_GetNoEntriesText(self.selectedCategory, self.selectedSubcategory, self.guildId)) - end end -function GuildHistoryManager:CompareGuildEvents(listEntry1, listEntry2) - return listEntry1.data.eventId > listEntry2.data.eventId -end +do + local function SortFunc(listEntry1, listEntry2) + return listEntry1.data.eventId > listEntry2.data.eventId + end -function GuildHistoryManager:SortScrollList() - local scrollData = ZO_ScrollList_GetDataList(self.list) - if #scrollData > 1 then - table.sort(scrollData, self.sortFunction) + function GuildHistoryManager:SortScrollList() + local scrollData = ZO_ScrollList_GetDataList(self.list) + if #scrollData > 1 then + table.sort(scrollData, SortFunc) + end end end @@ -288,7 +279,7 @@ end function GuildHistoryManager:OnGuildHistoryCategoryUpdated(guildId, category) if self.guildId == guildId and self.selectedCategory == category then - KEYBIND_STRIP:UpdateKeybindButtonGroup(self.keybindStripDescriptor) + self:UpdateKeybinds() self.refreshGroup:MarkDirty("EventListData") end end diff --git a/esoui/ingame/guild/keyboard/guildhistory_keyboard.xml b/esoui/ingame/guild/keyboard/guildhistory_keyboard.xml index 3c77eb117..84dd3f813 100755 --- a/esoui/ingame/guild/keyboard/guildhistory_keyboard.xml +++ b/esoui/ingame/guild/keyboard/guildhistory_keyboard.xml @@ -3,8 +3,15 @@ @@ -190,14 +197,10 @@ - - - - - - + diff --git a/esoui/pregame/accountlogin/keyboard/zo_login.lua b/esoui/pregame/accountlogin/keyboard/zo_login.lua index 6b5ce7b59..bd40ccaec 100755 --- a/esoui/pregame/accountlogin/keyboard/zo_login.lua +++ b/esoui/pregame/accountlogin/keyboard/zo_login.lua @@ -16,11 +16,7 @@ end local function OnLinkClicked(link, button, text, color, linkType, ...) if not ZO_PEGI_IsDeclineNotificationShowing() and linkType == URL_LINK_TYPE then local url = table.concat({...}, ':') - if IsHeronUI() then - ConfirmOpenURL(url) - else - RequestOpenURL(url, text) - end + RequestOpenURL(url, text) return true end end diff --git a/esoui/pregame/accountlogin/keyboard/zo_loginmanager.lua b/esoui/pregame/accountlogin/keyboard/zo_loginmanager.lua index 6f4c645f4..065796945 100644 --- a/esoui/pregame/accountlogin/keyboard/zo_loginmanager.lua +++ b/esoui/pregame/accountlogin/keyboard/zo_loginmanager.lua @@ -93,6 +93,7 @@ function LoginManager_Keyboard:AttemptLinkedLogin() end function LoginManager_Keyboard:AttemptCreateAccount(email, ageValid, emailSignup, country, requestedAccountName) + self.isLinking = nil ZO_Dialogs_ShowDialog("CREATING_ACCOUNT_KEYBOARD") PregameSetAccountCreationInfo(email, ageValid, emailSignup, country, requestedAccountName) PregameCreateAccount() @@ -104,6 +105,11 @@ function LoginManager_Keyboard:AttemptAccountLink(username, password) PregameLinkAccount(username, password) end +function LoginManager_Keyboard:RequestAccountActivationCode() + self.isLinking = true + RequestLinkAccountActivationCode() +end + function LoginManager_Keyboard:OnCreateLinkAccountSuccessful() ZO_Dialogs_ReleaseDialog(self.isLinking and "LINKING_ACCOUNTS_KEYBOARD" or "CREATING_ACCOUNT_KEYBOARD") @@ -182,9 +188,7 @@ end function LoginManager_Keyboard:OnProfileNotLinked() ZO_Dialogs_ReleaseDialog("LINKED_LOGIN_KEYBOARD") - if not IsHeronUI() then - self:SwitchToCreateLinkAccountFragment() - end + self:SwitchToCreateLinkAccountFragment() end function LoginManager_Keyboard:OnLoginSuccessful() @@ -261,7 +265,7 @@ function LoginManager_Keyboard:OnOTPPending(otpReason, otpType, otpDurationInSec local dialogName, textParams if otpReason == LOGIN_STATUS_OTP_PENDING then dialogName = "PROVIDE_OTP_INITIAL" - textParams = { GetString(OTP_DIALOG_SUBMIT), otpDurationMs } + textParams = { GetString(SI_OTP_DIALOG_SUBMIT), otpDurationMs } elseif otpReason == LOGIN_STATUS_OTP_FAILED then dialogName = "PROVIDE_OTP_SUBSEQUENT" textParams = { otpDurationMs } diff --git a/esoui/pregame/chapterupgrade/chapterupgrade_shared.lua b/esoui/pregame/chapterupgrade/chapterupgrade_shared.lua index 4fd0a6632..f90350354 100644 --- a/esoui/pregame/chapterupgrade/chapterupgrade_shared.lua +++ b/esoui/pregame/chapterupgrade/chapterupgrade_shared.lua @@ -59,9 +59,13 @@ function ZO_ChapterUpgrade_Shared:Initialize(control, sceneName) end function ZO_ChapterUpgrade_Shared:OnChapterUpgradeDataUpdated() - local chapterUpgradeId = GetCurrentChapterUpgradeId() - if IsChapterOwned(chapterUpgradeId) then - self:Hide() + -- Note that EVENT_ENTITLEMENT_STATE_CHANGED could happen before we've fully loaded data + -- If we're showing then we should be fine, plus we only want to handle this if we're showing to begin with + if SCENE_MANAGER:IsShowing(self.sceneName) then + local chapterUpgradeId = GetCurrentChapterUpgradeId() + if IsChapterOwned(chapterUpgradeId) then + self:Hide() + end end end diff --git a/esoui/pregame/charactercreate/gamepad/zo_charactercreate_gamepad.lua b/esoui/pregame/charactercreate/gamepad/zo_charactercreate_gamepad.lua index 2308727b0..bf844e269 100755 --- a/esoui/pregame/charactercreate/gamepad/zo_charactercreate_gamepad.lua +++ b/esoui/pregame/charactercreate/gamepad/zo_charactercreate_gamepad.lua @@ -41,6 +41,8 @@ local CHARACTER_EDIT_PREVIEW_GEAR_INFO = -- Slider Randomization Helper...all sliders share the sliderObject from the top control, so this just helps cut down on duplicate functions local function RandomizeSlider(control, randomizeType) control.sliderObject:Randomize(randomizeType) + --Re-narrate after randomizing + GAMEPAD_BUCKET_MANAGER:NarrateCurrentBucket() end -- Character Create Slider and Appearance Slider Managers @@ -289,6 +291,9 @@ function ZO_CharacterCreate_Gamepad:InitializeControls() updateFn = UpdateSlider, randomizeFn = RandomizeSlider, shouldAdd = IsAppearanceChangeEnabled, + narrationText = function(entryData, entryControl) + return self.physiqueTriangle:GetNarrationText() + end, }, [GAMEPAD_BUCKET_CUSTOM_CONTROL_FACE] = { @@ -296,6 +301,9 @@ function ZO_CharacterCreate_Gamepad:InitializeControls() updateFn = UpdateSlider, randomizeFn = RandomizeSlider, shouldAdd = IsAppearanceChangeEnabled, + narrationText = function(entryData, entryControl) + return self.faceTriangle:GetNarrationText() + end, }, } end @@ -336,7 +344,7 @@ function ZO_CharacterCreate_Gamepad:OnStateChanged(oldState, newState) -- that may change our focus control which will impact the keybinds self:RefreshKeybindStrip() elseif newState == SCENE_HIDDEN then - -- Save unsaved settings to manager so they can be applied on a platform swap for stadia + -- Save unsaved settings to manager so they can be applied on a platform swap for i, controlList in pairs(self.controls) do for j, control in pairs(controlList) do local controlInfo = control.info @@ -510,6 +518,8 @@ function ZO_CharacterCreate_Gamepad:GenerateKeybindingDescriptor() self.focusControl:ToggleLocked() PlaySound(callbackSound) self:RefreshKeybindStrip() + --Re-narrate when the lock state changes + GAMEPAD_BUCKET_MANAGER:NarrateCurrentBucket() end, } end @@ -542,6 +552,10 @@ function ZO_CharacterCreate_Gamepad:GenerateKeybindingDescriptor() self:UpdateCollectibleBlockingInfoTooltip(selectedInfo) self:RefreshKeybindStrip() + + --Re-narrate when the preview state changes + local NARRATE_HEADER = true + GAMEPAD_BUCKET_MANAGER:NarrateCurrentBucket(NARRATE_HEADER) end, } @@ -925,7 +939,14 @@ function ZO_CharacterCreate_Gamepad:ResetControls() narrationText = function(entryData, entryControl) return entryData.control.sliderObject:GetNarrationText() end, - directionalInputNarrationFunction = ZO_GetNumericHorizontalDirectionalInputNarrationData, + directionalInputNarrationFunction = function() + --Exclude directional input when locked + if slider:IsLocked() then + return {} + else + return ZO_GetNumericHorizontalDirectionalInputNarrationData() + end + end, } slider.info = info controlData[#controlData + 1] = info @@ -965,7 +986,14 @@ function ZO_CharacterCreate_Gamepad:ResetControls() narrationText = function(entryData, entryControl) return entryData.control.sliderObject:GetNarrationText() end, - directionalInputNarrationFunction = ZO_GetHorizontalDirectionalInputNarrationData, + directionalInputNarrationFunction = function() + --Exclude directional input when locked + if slider:IsLocked() then + return {} + else + return ZO_GetHorizontalDirectionalInputNarrationData() + end + end, } slider.info = info controlData[#controlData + 1] = info @@ -1103,25 +1131,39 @@ function ZO_CharacterCreate_Gamepad:InitializeClassSelectors() -- 4 is the default number of classes and they are laid out -- so that the fourth class is in the middle column layoutTable = { - ZO_CharacterCreate_GamepadClassColumn11, - ZO_CharacterCreate_GamepadClassColumn21, - ZO_CharacterCreate_GamepadClassColumn31, - ZO_CharacterCreate_GamepadClassColumn22, + ZO_CharacterCreate_GamepadClassColumn1Row1, + ZO_CharacterCreate_GamepadClassColumn2Row1, + ZO_CharacterCreate_GamepadClassColumn3Row1, + ZO_CharacterCreate_GamepadClassColumn2Row2, + } + -- If we have 7 classes, we need to add the seventh in the center column + elseif numClasses == 7 then + layoutTable = { + ZO_CharacterCreate_GamepadClassColumn1Row1, + ZO_CharacterCreate_GamepadClassColumn2Row1, + ZO_CharacterCreate_GamepadClassColumn3Row1, + ZO_CharacterCreate_GamepadClassColumn1Row2, + ZO_CharacterCreate_GamepadClassColumn2Row2, + ZO_CharacterCreate_GamepadClassColumn3Row2, + ZO_CharacterCreate_GamepadClassColumn2Row3, } else - -- if we have 5 or 6 classes, then we can lay them out normally + -- if we have 5 or 6 classes, or 8 or 9, then we can lay them out normally -- from left to right without worrying about centering one. - -- We aren't dynamically creating controls so if we have more than 6 classes we won't have enough controls, + -- We aren't dynamically creating controls so if we have more than 9 classes we won't have enough controls, -- and more controls will have to be added to the XML and additional logic to correctly lay them out. -- Rather than assert and break the whole UI, we'll just display what we can, and DevCharacterCreate will show a big red error label. layoutTable = { - ZO_CharacterCreate_GamepadClassColumn11, - ZO_CharacterCreate_GamepadClassColumn21, - ZO_CharacterCreate_GamepadClassColumn31, - ZO_CharacterCreate_GamepadClassColumn12, - ZO_CharacterCreate_GamepadClassColumn22, - ZO_CharacterCreate_GamepadClassColumn32, + ZO_CharacterCreate_GamepadClassColumn1Row1, + ZO_CharacterCreate_GamepadClassColumn2Row1, + ZO_CharacterCreate_GamepadClassColumn3Row1, + ZO_CharacterCreate_GamepadClassColumn1Row2, + ZO_CharacterCreate_GamepadClassColumn2Row2, + ZO_CharacterCreate_GamepadClassColumn3Row2, + ZO_CharacterCreate_GamepadClassColumn1Row3, + ZO_CharacterCreate_GamepadClassColumn2Row3, + ZO_CharacterCreate_GamepadClassColumn3Row3, } end @@ -1650,15 +1692,15 @@ function ZO_CharacterNaming_Gamepad_CreateDialog(self, params) parametricDialog.noViolations = #parametricDialog.nameViolations == 0 parametricDialog.selectedName = CorrectCharacterNameCase(parametricDialog.selectedName) + parametricDialog.violationText = nil if not parametricDialog.noViolations then if suppressErrors then SCENE_MANAGER:RemoveFragment(params.errorFragment) else local HIDE_UNVIOLATED_RULES = true - local violationString = ZO_ValidNameInstructions_GetViolationString(parametricDialog.selectedName, parametricDialog.nameViolations, HIDE_UNVIOLATED_RULES, SI_CREATE_CHARACTER_GAMEPAD_INVALID_NAME_DIALOG_INSTRUCTION_FORMAT) - - self.errorLabel:SetText(violationString) + parametricDialog.violationText = ZO_ValidNameInstructions_GetViolationString(parametricDialog.selectedName, parametricDialog.nameViolations, HIDE_UNVIOLATED_RULES, SI_CREATE_CHARACTER_GAMEPAD_INVALID_NAME_DIALOG_INSTRUCTION_FORMAT) + self.errorLabel:SetText(parametricDialog.violationText) SCENE_MANAGER:AddFragment(params.errorFragment) end else @@ -1705,6 +1747,13 @@ function ZO_CharacterNaming_Gamepad_CreateDialog(self, params) ZO_SharedGamepadEntry_OnSetup(control, data, selected, reselectingDuringRebuild, enabled, active) end + doneEntry.narrationText = function(entryData, entryControl) + local narrations = {} + ZO_AppendNarration(narrations, ZO_GetSharedGamepadEntryDefaultNarrationText(entryData, entryControl)) + ZO_AppendNarration(narrations, SCREEN_NARRATION_MANAGER:CreateNarratableObject(parametricDialog.violationText)) + return narrations + end + ZO_Dialogs_RegisterCustomDialog(params.dialogName, { @@ -1765,7 +1814,12 @@ function ZO_CharacterNaming_Gamepad_CreateDialog(self, params) self.editBoxControl = control.editBoxControl end, - narrationText = ZO_GetDefaultParametricListEditBoxNarrationText, + narrationText = function(entryData, entryControl) + local narrations = {} + ZO_AppendNarration(narrations, ZO_FormatEditBoxNarrationText(entryControl.editBoxControl)) + ZO_AppendNarration(narrations, SCREEN_NARRATION_MANAGER:CreateNarratableObject(parametricDialog.violationText)) + return narrations + end, }, }, -- Done menu item diff --git a/esoui/pregame/charactercreate/gamepad/zo_charactercreate_gamepad.xml b/esoui/pregame/charactercreate/gamepad/zo_charactercreate_gamepad.xml index 4d411ecee..43e89f09f 100755 --- a/esoui/pregame/charactercreate/gamepad/zo_charactercreate_gamepad.xml +++ b/esoui/pregame/charactercreate/gamepad/zo_charactercreate_gamepad.xml @@ -65,12 +65,16 @@ - - + + @@ -224,7 +228,7 @@ - + - + - + + + + + + ZO_TributeConfinementViewerCardTile_Keyboard_OnInitialized(self) + + + + \ No newline at end of file diff --git a/esoui/publicallingames/tribute/tributecard.lua b/esoui/publicallingames/tribute/tributecard.lua index 25546d683..b36fb0ec5 100644 --- a/esoui/publicallingames/tribute/tributecard.lua +++ b/esoui/publicallingames/tribute/tributecard.lua @@ -113,7 +113,7 @@ do [TRIBUTE_MECHANIC_ACTIVATION_SOURCE_COMBO] = "Combo", } - internalassert(TRIBUTE_MECHANIC_ITERATION_END == 13, "A new Tribute mechanic has been added. Does the MECHANIC_PARAM_MODIFIERS need special modifiers for this mechanic?") + internalassert(TRIBUTE_MECHANIC_ITERATION_END == 15, "A new Tribute mechanic has been added. Does the MECHANIC_PARAM_MODIFIERS need special modifiers for this mechanic?") local MECHANIC_PARAM_MODIFIERS = { [TRIBUTE_MECHANIC_HEAL_AGENT] = @@ -145,6 +145,7 @@ do self.cardDefId = cardObject:GetCardDefId() self.activationSource = activationSource self.mechanicIndex = mechanicIndex + local triggerId self.tributeMechanicType, self.quantity, self.comboNum, self.param1, self.param2, self.param3, triggerId = cardObject:GetMechanicInfo(activationSource, mechanicIndex) self.numSiblings = cardObject:GetNumMechanics(activationSource) local isOnActivation = activationSource == TRIBUTE_MECHANIC_ACTIVATION_SOURCE_ACTIVATION @@ -721,6 +722,16 @@ function ZO_TributeCard:SetCardInstanceId(cardInstanceId) self:OnStateFlagsChanged(GetTributeCardStateFlags(cardInstanceId)) end +function ZO_TributeCard:GetNumConfinedCards() + return GetNumConfinedTributeCards(self:GetCardInstanceId()) +end + +function ZO_TributeCard:ShowConfinedCards(previousViewer) + if self:GetNumConfinedCards() > 0 then + ZO_TRIBUTE_CONFINEMENT_VIEWER_MANAGER:SetViewingAgent(self:GetCardInstanceId(), previousViewer) + end +end + function ZO_TributeCard:GetMechanicContainer(mechanicActivationSource, mechanicIndex) for _, mechanicContainer in ipairs(self.mechanicContainers) do local activationSource, index = mechanicContainer:GetActivationSourceAndIndex() @@ -1027,6 +1038,7 @@ function ZO_TributeCard:ReleaseAllObjects() self:ReleasePopupAnimation() self:ReleaseStateEffects() self:ReleaseTriggerAnimations() + self:ReleaseStackedCardBackTextures() end function ZO_TributeCard:ReleaseAlphaAnimation() @@ -1055,6 +1067,16 @@ function ZO_TributeCard:ReleaseMechanics() ZO_ClearNumericallyIndexedTable(self.mechanicContainers) end +function ZO_TributeCard:ReleaseStackedCardBackTextures() + if self.stackedCardBackTextures and #self.stackedCardBackTextures > 0 then + local cardBackPool = TRIBUTE_POOL_MANAGER:GetStackedCardBackTexturePool() + for _, texture in ipairs(self.stackedCardBackTextures) do + cardBackPool:ReleaseObject(texture.key) + end + ZO_ClearNumericallyIndexedTable(self.stackedCardBackTextures) + end +end + function ZO_TributeCard:ReleasePopupAnimation() local timeline = self.popupTimeline if timeline then @@ -1166,6 +1188,11 @@ function ZO_TributeCard:IsInteractive() return false end + if IsTributeCardConfined(self:GetCardInstanceId()) then + --Suppress interaction for confined cards + return false + end + return true end @@ -1191,8 +1218,8 @@ end function ZO_TributeCard:OnMouseUp(button, upInside) if TRIBUTE:IsInputStyleMouse() and upInside and button == MOUSE_BUTTON_INDEX_LEFT and self.cardInstanceId then - -- Don't allow interaction with cards while the target viewer is up - if ZO_TRIBUTE_TARGET_VIEWER_MANAGER:IsViewingTargets() then + -- Don't allow interaction with cards while a viewer is up + if TRIBUTE:GetActiveViewer() ~= nil then return end InteractWithTributeCard(self.cardInstanceId) @@ -1277,19 +1304,59 @@ function ZO_TributeCard:ShowAsPopup(screenX, screenY, popupType) self.popupTimeline = timeline end timeline:PlayForward() + --If this card has confined cards and will be showing a keybind for it, we need to adjust the inset to account for the keybind underneath + if TRIBUTE:CanShowConfineKeybind() and self:GetNumConfinedCards() > 0 then + local BOTTOM_INSET = ZO_TRIBUTE_CONFINED_CARDS_KEYBIND_HEIGHT + ZO_TRIBUTE_CONFINED_CARDS_KEYBIND_OFFSET_Y + control:SetClampedToScreenInsets(0, 0, 0, BOTTOM_INSET) + end + --Only the CARD popup type should show a confined stack + self:RefreshConfinedStack() elseif popupType == ZO_TRIBUTE_CARD_POPUP_TYPE.MECHANIC then control:SetAnchor(LEFT, GuiRoot, TOPLEFT, screenX, screenY) end - if ZO_TRIBUTE_TARGET_VIEWER_MANAGER:IsViewingTargets() then - local bottom = IsInGamepadPreferredMode() and ZO_KEYBIND_STRIP_GAMEPAD_VISUAL_HEIGHT or ZO_KEYBIND_STRIP_KEYBOARD_VISUAL_HEIGHT - control:SetClampedToScreenInsets(0, 0, 0, bottom) + --If there is a viewer up, check to see if we need to adjust the insets to account for a keybind strip + local activeViewer = TRIBUTE:GetActiveViewer() + if activeViewer and activeViewer:IsKeybindStripVisible() then + local BOTTOM_INSET = IsInGamepadPreferredMode() and ZO_KEYBIND_STRIP_GAMEPAD_VISUAL_HEIGHT or ZO_KEYBIND_STRIP_KEYBOARD_VISUAL_HEIGHT + control:SetClampedToScreenInsets(0, 0, 0, BOTTOM_INSET) end control:SetClampedToScreen(true) control:SetHidden(false) self:SetMouseEnabled(false) end +do + local ADDITIONAL_CARDS_CONFINED_ICON = "EsoUI/Art/Tribute/tribute_icon_additionalCardsConfined.dds" + function ZO_TributeCard:PopulateConfinedCards(cardControls) + local numConfined = self:GetNumConfinedCards() + local numControls = #cardControls + + for i, cardControl in ipairs(cardControls) do + if i > numConfined then + --If the index for this card control exceeds the number of cards we actually have confined, hide it + cardControl:SetHidden(true) + else + if i == numControls and numConfined > numControls then + --Special case: If we have more confined cards than we do controls to show it, we use the last control to represent that instead of showing it as an individual card + local additionalQuantity = numConfined - (numControls - 1) + cardControl.portrait:SetTexture(ADDITIONAL_CARDS_CONFINED_ICON) + --Calculate and show the number of non-visible confined cards + cardControl.quantity:SetText(additionalQuantity) + cardControl.quantity:SetHidden(false) + else + --Get the portrait for the confined card in question and set it + local confinedInstanceId = GetConfinedTributeCardInstanceId(self:GetCardInstanceId(), i) + local cardId, patronId = GetTributeCardInstanceDefIds(confinedInstanceId) + cardControl.portrait:SetTexture(GetTributeCardPortrait(cardId)) + cardControl.quantity:SetHidden(true) + end + cardControl:SetHidden(false) + end + end + end +end + function ZO_TributeCard:OnAlphaTimelineStopped(timeline) if timeline == self.alphaTimeline and timeline:IsPlayingBackward() then self:ReleaseAlphaAnimation() @@ -1336,6 +1403,44 @@ function ZO_TributeCard:GetScreenAnchorPosition(anchor) return screenX, screenY end +function ZO_TributeCard:RefreshConfinedStack() + self:ReleaseStackedCardBackTextures() + local numConfinedCards = self:GetNumConfinedCards() + if numConfinedCards > 0 then + --Only create this table if we need it + if not self.stackedCardBackTextures then + self.stackedCardBackTextures = {} + end + + local maxCardsInStack = GetMaxTributeCardsInStack() + local previousControl = nil + + for i = 1, numConfinedCards do + --Only show individual card back textures up to the maximum number of cards we can show in a stack + --We do < instead of <= because the jailer itself counts towards this number + if i < maxCardsInStack then + local cardBackTexture, key = TRIBUTE_POOL_MANAGER:GetStackedCardBackTexturePool():AcquireObject() + cardBackTexture.key = key + + cardBackTexture:SetParent(self.control) + --Each card back texture should be one level lower than the last + cardBackTexture:SetDrawLevel(maxCardsInStack - i) + + --Anchor the cards slightly differently depending on how many there are + if numConfinedCards > 1 then + cardBackTexture:SetAnchor(TOPLEFT, previousControl, TOPLEFT, 10, -10) + else + cardBackTexture:SetAnchor(TOPLEFT, previousControl, TOPLEFT, 15, -15) + end + cardBackTexture:SetHidden(false) + + previousControl = cardBackTexture + table.insert(self.stackedCardBackTextures, cardBackTexture) + end + end + end +end + -- Global Functions -- function ZO_TributeCard_OnInitialized(...) diff --git a/esoui/publicallingames/tribute/tributecard.xml b/esoui/publicallingames/tribute/tributecard.xml index c57bf60b6..22fba746a 100644 --- a/esoui/publicallingames/tribute/tributecard.xml +++ b/esoui/publicallingames/tribute/tributecard.xml @@ -282,19 +282,19 @@ - + ZO_TributeCard_MechanicContainer_OnInitialized(self) - + - + - @@ -302,9 +302,9 @@ - + - -