-- Shared object class ZO_SharedSmithingImprovement = ZO_Object:Subclass() function ZO_SharedSmithingImprovement:New(...) local smithingImprovement = ZO_Object.New(self) smithingImprovement:Initialize(...) return smithingImprovement end function ZO_SharedSmithingImprovement:Initialize(listControl, boosterContainerControl, resultTooltipControl, owner) self.owner = owner self.listControl = listControl self.resultTooltip = resultTooltipControl self.boosterContainer = boosterContainerControl self:InitializeSlots() self:InitializeBoosterRows() self:HandleDirtyEvent() end function ZO_SharedSmithingImprovement:InitializeBoosterRows() self.rows = {} self.boosterHeaderLabel = self.boosterContainer:GetNamedChild("Header") local currentAnchor = ZO_Anchor:New(TOPLEFT, self.boosterContainer) local function InitializeRow(row, from, to) row.fromLabel = self.boosterContainer:GetNamedChild(from) row.toLabel = self.boosterContainer:GetNamedChild(to) if row.toLabel then row.questPin = row.toLabel:GetNamedChild("QuestPin") end row.fadeAnimation = ANIMATION_MANAGER:CreateTimelineFromVirtual("SmithingImprovementBoosterFade", row) row.iconTexture = row:GetNamedChild("Icon") row.stackLabel = row.iconTexture:GetNamedChild("StackCount") return row end self.rows = { InitializeRow(self.boosterContainer:GetNamedChild("NormalToFine"), "Normal", "Fine"), InitializeRow(self.boosterContainer:GetNamedChild("FineToSuperior"), "Fine", "Superior"), InitializeRow(self.boosterContainer:GetNamedChild("SuperiorToEpic"), "Superior", "Epic"), InitializeRow(self.boosterContainer:GetNamedChild("EpicToLegendary"), "Epic", "Legendary"), } for i, row in ipairs(self.rows) do row.index = i end local function InitializeQualityLabel(label, displayQuality) label:SetText(GetString("SI_ITEMQUALITY", displayQuality)) label:SetColor(GetInterfaceColor(INTERFACE_COLOR_TYPE_ITEM_QUALITY_COLORS, displayQuality)) label.fadeAnimation = ANIMATION_MANAGER:CreateTimelineFromVirtual("SmithingImprovementBoosterFade", label) end InitializeQualityLabel(self.boosterContainer:GetNamedChild("Normal"), ITEM_DISPLAY_QUALITY_NORMAL) InitializeQualityLabel(self.boosterContainer:GetNamedChild("Fine"), ITEM_DISPLAY_QUALITY_MAGIC) InitializeQualityLabel(self.boosterContainer:GetNamedChild("Superior"), ITEM_DISPLAY_QUALITY_ARCANE) InitializeQualityLabel(self.boosterContainer:GetNamedChild("Epic"), ITEM_DISPLAY_QUALITY_ARTIFACT) InitializeQualityLabel(self.boosterContainer:GetNamedChild("Legendary"), ITEM_DISPLAY_QUALITY_LEGENDARY) end function ZO_SharedSmithingImprovement:RefreshBoosterRows() for i, row in ipairs(self.rows) do local reagentName, icon, stack, _, _, _, _, functionalQuality, displayQuality = GetSmithingImprovementItemInfo(GetCraftingInteractionType(), i) row.reagentName = reagentName row.currentStack = stack row.functionalQuality = functionalQuality row.displayQuality = displayQuality -- row.quality is deprecated, included here for addon backwards compatibility row.quality = displayQuality row.icon = icon row.stackLabel:SetText(stack) if stack == 0 then row.stackLabel:SetColor(ZO_ERROR_COLOR:UnpackRGBA()) else row.stackLabel:SetColor(ZO_SELECTED_TEXT:UnpackRGBA()) end row.iconTexture:SetTexture(icon) end end function ZO_SharedSmithingImprovement:HandleDirtyEvent() if self.listControl:IsHidden() then self.dirty = true else self:Refresh() end end function ZO_SharedSmithingImprovement:SetCraftingType(craftingType, oldCraftingType, isCraftingTypeDifferent) if isCraftingTypeDifferent then local chartString = ZO_SharedSmithingImprovement_GetBoosterChartStringForCraftingType(craftingType) self.boosterHeaderLabel:SetText(chartString) end self.improvementSlot:SetItem(nil) self.inventory:HandleDirtyEvent() end function ZO_SharedSmithingImprovement:Refresh() if ZO_CraftingUtils_IsPerformingCraftProcess() then -- Don't update improvement panel until the animation is complete: ESO-556307 return end self.dirty = false self:OnSlotChanged() end function ZO_SharedSmithingImprovement:OnSlotChanged() self:RefreshBoosterRows(self) self.currentQuality = nil local hasItem = self.improvementSlot:HasItem() if hasItem then local row = self:GetRowForSelection() if row then local maxBoosters = self:FindMaxBoostersToApply() self.spinner:SetMinMax(1, maxBoosters) self.spinner:SetValue(maxBoosters) self.spinner:SetSoftMax(row.currentStack) -- row.quality is deprecated, included here for addon backwards compatibility self.currentQuality = (row.functionalQuality and row.functionalQuality - 1) or (row.quality and row.quality -1) -- need the "from" quality self.boosterSlot.craftingType = GetCraftingInteractionType() self.boosterSlot.index = row.index ZO_ItemSlot_SetupSlot(self.boosterSlot, row.currentStack, row.icon) self:RefreshImprovementChance() else self:ClearSelections() return end else self.canImprove = false self.improvementChanceLabel:SetText(GetString(SI_SMITHING_IMPROVE_CHANCE_HEADER)) self:ClearBoosterRowHighlight() self.owner:OnImprovementSlotChanged() end self.boosterSlot:SetHidden(not hasItem) if hasItem then self.resultTooltip:SetHidden(false) self:SetupResultTooltip(self:GetCurrentImprovementParams()) else self.resultTooltip:SetHidden(true) end end function ZO_SharedSmithingImprovement:GetBoosterRowForQuality(functionalQuality) for i, row in ipairs(self.rows) do -- row.quality is deprecated, included here for addon backwards compatibility local rowFunctionalQuality = row.functionalQuality or row.quality if rowFunctionalQuality - 1 == functionalQuality then return row end end end function ZO_SharedSmithingImprovement:OnInventoryUpdate(validItems) self.improvementSlot:ValidateSlottedItem(validItems) self:Refresh() end function ZO_SharedSmithingImprovement:ShowAppropriateSlotDropCallouts() self.improvementSlot:ShowDropCallout() end function ZO_SharedSmithingImprovement:HideAllSlotDropCallouts() self.improvementSlot:HideDropCallout() end function ZO_SharedSmithingImprovement:FindMaxBoostersToApply() local numBoostersToApply = 0 local itemToImproveBagId, itemToImproveSlotIndex, craftingType = self:GetCurrentImprovementParams() repeat numBoostersToApply = numBoostersToApply + 1 local chance = GetSmithingImprovementChance(itemToImproveBagId, itemToImproveSlotIndex, numBoostersToApply, craftingType) until chance >= 100.0 or numBoostersToApply == 1000 return numBoostersToApply end function ZO_SharedSmithingImprovement:GetRowForSelection() if self.improvementSlot:HasItem() then local functionalQuality = GetItemFunctionalQuality(self.improvementSlot:GetBagAndSlot()) return self:GetBoosterRowForQuality(functionalQuality) end end function ZO_SharedSmithingImprovement:GetCurrentImprovementParams() if self.improvementSlot:HasItem() then local bagId, slotIndex = self.improvementSlot:GetBagAndSlot() return bagId, slotIndex, GetCraftingInteractionType() end end function ZO_SharedSmithingImprovement:RefreshImprovementChance() if self.improvementSlot:HasItem() and self.currentQuality then local itemToImproveBagId, itemToImproveSlotIndex, craftingType = self:GetCurrentImprovementParams() local numBoostersToApply = self:GetNumBoostersToApply() local chance = GetSmithingImprovementChance(itemToImproveBagId, itemToImproveSlotIndex, numBoostersToApply, craftingType) chance = zo_roundToNearest(chance, .1) self.improvementChanceLabel:SetText(zo_strformat(SI_SMITHING_IMPROVE_CHANCE_FORMAT, chance)) local row = self:GetBoosterRowForQuality(self.currentQuality) self.canImprove = numBoostersToApply <= row.currentStack end self.owner:OnImprovementSlotChanged() end function ZO_SharedSmithingImprovement:GetNumBoostersToApply() return self.spinner:GetValue() end function ZO_SharedSmithingImprovement:IsItemAlreadySlottedToCraft(bagId, slotIndex) return self.improvementSlot:IsItemId(GetItemInstanceId(bagId, slotIndex)) end function ZO_SharedSmithingImprovement:CanItemBeAddedToCraft(bagId, slotIndex) return true -- currently no requirements to meet before being able to improve end function ZO_SharedSmithingImprovement:AddItemToCraft(bagId, slotIndex) self:SetImprovementSlotItem(bagId, slotIndex) end function ZO_SharedSmithingImprovement:RemoveItemFromCraft(bagId, slotIndex) self:ClearSelections() end function ZO_SharedSmithingImprovement:SetImprovementSlotItem(bagId, slotIndex) self.improvementSlot:SetItem(bagId, slotIndex) end function ZO_SharedSmithingImprovement:OnFilterChanged(filterType) if self.awaitingLabel then self.awaitingLabel:SetText(GetString("SI_SMITHINGFILTERTYPE_IMPROVEAWAITING", filterType)) end end function ZO_SharedSmithingImprovement:IsImprovable() return self.canImprove end function ZO_SharedSmithingImprovement:HasSelections() return self.improvementSlot:HasItem() end function ZO_SharedSmithingImprovement:ClearSelections() self:SetImprovementSlotItem(nil) end function ZO_SharedSmithingImprovement:IsSlotted(bagId, slotIndex) return self.improvementSlot:IsBagAndSlot(bagId, slotIndex) end function ZO_SharedSmithingImprovement:Improve() if ZO_CraftingUtils_IsPerformingCraftProcess() then -- Handle edge case where player hits R and E at the same time. return end local itemToImproveBagId, itemToImproveSlotIndex, craftingType = self:GetCurrentImprovementParams() local numBoostersToApply = self:GetNumBoostersToApply() local isItemLocked = IsItemPlayerLocked(itemToImproveBagId, itemToImproveSlotIndex) local chance = GetSmithingImprovementChance(itemToImproveBagId, itemToImproveSlotIndex, numBoostersToApply, craftingType) if isItemLocked and chance < 100 then ZO_Alert(UI_ALERT_CATEGORY_ALERT, nil, GetString(SI_CRAFTING_ALERT_CANT_IMPROVE_LOCKED_ITEM)) return end local improveItemLink = GetItemLink(itemToImproveBagId, itemToImproveSlotIndex) local dialogName = "CONFIRM_IMPROVE_ITEM" if isItemLocked then if IsInGamepadPreferredMode() then dialogName = "GAMEPAD_CONFIRM_IMPROVE_LOCKED_ITEM" else dialogName = "CONFIRM_IMPROVE_LOCKED_ITEM" end end local function ShowImprovementDialog() ZO_Dialogs_ShowPlatformDialog(dialogName, { bagId = itemToImproveBagId, slotIndex = itemToImproveSlotIndex, boostersToApply = numBoostersToApply, chance = chance, }, {mainTextParams = { chance, improveItemLink, GetString(SI_PERFORM_ACTION_CONFIRMATION)}}) end if IsItemBoPAndTradeable(itemToImproveBagId, itemToImproveSlotIndex) then ZO_Dialogs_ShowPlatformDialog("CONFIRM_MODIFY_TRADE_BOP", {onAcceptCallback = ShowImprovementDialog}, {mainTextParams={GetItemName(itemToImproveBagId, itemToImproveSlotIndex)}}) else ShowImprovementDialog() end end -- Crafting slot ZO_SmithingImprovementSlot = ZO_CraftingSlotBase:Subclass() function ZO_SmithingImprovementSlot:New(...) return ZO_CraftingSlotBase.New(self, ...) end function ZO_SmithingImprovementSlot:Initialize(owner, control, slotType, craftingInventory) ZO_CraftingSlotBase.Initialize(self, owner, control, slotType, "", craftingInventory) self.nameLabel = control:GetNamedChild("Name") end function ZO_SmithingImprovementSlot:SetItem(bagId, slotIndex) local hadItem = self:HasItem() local oldItemInstanceId = self:GetItemId() self:SetupItem(bagId, slotIndex) if self:HasItem() then if oldItemInstanceId ~= self:GetItemId() then PlaySound(SOUNDS.SMITHING_ITEM_TO_IMPROVE_PLACED) end elseif hadItem then PlaySound(SOUNDS.SMITHING_ITEM_TO_IMPROVE_REMOVED) end end function ZO_SmithingImprovementSlot:Refresh() ZO_CraftingSlotBase.Refresh(self) if self.nameLabel then if self:HasItem() then self.nameLabel:SetHidden(false) self.nameLabel:SetText(zo_strformat(SI_TOOLTIP_ITEM_NAME, GetItemName(self:GetBagAndSlot()))) local displayQuality = GetItemDisplayQuality(self:GetBagAndSlot()) self.nameLabel:SetColor(GetInterfaceColor(INTERFACE_COLOR_TYPE_ITEM_QUALITY_COLORS, displayQuality)) else self.nameLabel:SetHidden(true) end end end function ZO_SmithingImprovementSlot:ShowDropCallout() self.dropCallout:SetHidden(false) self.dropCallout:SetTexture("EsoUI/Art/Crafting/crafting_alchemy_goodSlot.dds") end -- Shared helper functions (formerly local to the PC version) function ZO_SharedSmithingImprovement_GetBoosterChartStringForCraftingType(craftingType) if craftingType == CRAFTING_TYPE_BLACKSMITHING then return GetString(SI_SMITHING_BLACKSMITH_BOOSTER_CHART) elseif craftingType == CRAFTING_TYPE_CLOTHIER then return GetString(SI_SMITHING_CLOTHIER_BOOSTER_CHART) elseif craftingType == CRAFTING_TYPE_WOODWORKING then return GetString(SI_SMITHING_WOODWORKING_BOOSTER_CHART) elseif craftingType == CRAFTING_TYPE_JEWELRYCRAFTING then return GetString(SI_SMITHING_JEWELRYCRAFTING_BOOSTER_CHART) end end function ZO_SharedSmithingImprovement_GetImprovementTooltipSounds() local craftingType = GetCraftingInteractionType() if craftingType == CRAFTING_TYPE_BLACKSMITHING then return SOUNDS.BLACKSMITH_IMPROVE_TOOLTIP_GLOW_SUCCESS, SOUNDS.BLACKSMITH_IMPROVE_TOOLTIP_GLOW_FAIL elseif craftingType == CRAFTING_TYPE_CLOTHIER then return SOUNDS.CLOTHIER_IMPROVE_TOOLTIP_GLOW_SUCCESS, SOUNDS.CLOTHIER_IMPROVE_TOOLTIP_GLOW_FAIL elseif craftingType == CRAFTING_TYPE_WOODWORKING then return SOUNDS.WOODWORKER_IMPROVE_TOOLTIP_GLOW_SUCCESS, SOUNDS.WOODWORKER_IMPROVE_TOOLTIP_GLOW_FAIL elseif craftingType == CRAFTING_TYPE_JEWELRYCRAFTING then return SOUNDS.JEWELRYCRAFTER_IMPROVE_TOOLTIP_GLOW_SUCCESS, SOUNDS.JEWELRYCRAFTER_IMPROVE_TOOLTIP_GLOW_FAIL end end function ZO_SharedSmithingImprovement_CanItemBeImproved(itemData) return CanItemBeSmithingImproved(itemData.bagId, itemData.slotIndex, GetCraftingInteractionType()) end function ZO_SharedSmithingImprovement_DoesItemPassFilter(bagId, slotIndex, filterType) return ZO_CraftingUtils_GetSmithingFilterFromItem(bagId, slotIndex) == filterType end