-- sponsored by kivera-global.com -- remade by Vithrax#5814 Prey = {} preyWindow = nil preyButton = nil local preyTrackerButton local msgWindow local bankGold = 0 local inventoryGold = 0 local rerollPrice = 0 local bonusRerolls = 0 local PREY_BONUS_DAMAGE_BOOST = 0 local PREY_BONUS_DAMAGE_REDUCTION = 1 local PREY_BONUS_XP_BONUS = 2 local PREY_BONUS_IMPROVED_LOOT = 3 local PREY_BONUS_NONE = 4 local PREY_ACTION_LISTREROLL = 0 local PREY_ACTION_BONUSREROLL = 1 local PREY_ACTION_MONSTERSELECTION = 2 local PREY_ACTION_REQUEST_ALL_MONSTERS = 3 local PREY_ACTION_CHANGE_FROM_ALL = 4 local PREY_ACTION_OPTION = 5 local PREY_OPTION_UNTOGGLE = 0 local PREY_OPTION_TOGGLE_AUTOREROLL = 1 local PREY_OPTION_TOGGLE_LOCK_PREY = 2 local preyDescription = {} local raceEntriesBySlot = {} local selectedRaceEntryBySlot = {} local selectedRaceWidgetBySlot = {} local raceSearchTextsBySlot = {} local refreshRaceList local setRaceSelection local updateRaceSelectionDisplay local restoreRaceListItemBackground local setWidgetTreePhantom local updatePickSpecificPreyButton local refreshRerollButtonState function bonusDescription(bonusType, bonusValue, bonusGrade) if bonusType == PREY_BONUS_DAMAGE_BOOST then return 'Damage bonus (' .. bonusGrade .. '/10)' elseif bonusType == PREY_BONUS_DAMAGE_REDUCTION then return 'Damage reduction bonus (' .. bonusGrade .. '/10)' elseif bonusType == PREY_BONUS_XP_BONUS then return 'XP bonus (' .. bonusGrade .. '/10)' elseif bonusType == PREY_BONUS_IMPROVED_LOOT then return 'Loot bonus (' .. bonusGrade .. '/10)' else return 'Unknown bonus' end return 'Unknown bonus' end function timeleftTranslation(timeleft, forPreyTimeleft) -- in seconds if timeleft == 0 then if forPreyTimeleft then return tr('infinite bonus') end return tr('Free') end local hours = string.format('%02.f', math.floor(timeleft / 3600)) local mins = string.format('%02.f', math.floor(timeleft / 60 - (hours * 60))) return hours .. ':' .. mins end function init() connect(g_game, { onGameStart = check, onGameEnd = onGameEnd, onResourcesBalanceChange = Prey.onResourcesBalanceChange, onPreyFreeRerolls = onPreyFreeRerolls, onPreyTimeLeft = onPreyTimeLeft, onPreyRerollPrice = onPreyRerollPrice, onPreyLocked = onPreyLocked, onPreyInactive = onPreyInactive, onPreyActive = onPreyActive, onPreySelection = onPreySelection, onPreySelectionChangeMonster = onPreySelectionChangeMonster, onPreyListSelection = onPreyListSelection, onPreyWildcardSelection = onPreyWildcardSelection }) preyWindow = g_ui.displayUI('prey') preyWindow:hide() preyTracker = g_ui.createWidget('PreyTracker', modules.game_interface.getRightPanel()) preyTracker:setup() preyTracker:setContentMaximumHeight(110) preyTracker:setContentMinimumHeight(70) preyTracker:hide() -- Hide buttons similar to unjustifiedpoints implementation local toggleFilterButton = preyTracker:recursiveGetChildById('toggleFilterButton') if toggleFilterButton then toggleFilterButton:setVisible(false) end local contextMenuButton = preyTracker:recursiveGetChildById('contextMenuButton') if contextMenuButton then contextMenuButton:setVisible(false) end local newWindowButton = preyTracker:recursiveGetChildById('newWindowButton') if newWindowButton then newWindowButton:setVisible(false) end -- Set up the miniwindow title and icon local titleWidget = preyTracker:getChildById('miniwindowTitle') if titleWidget then titleWidget:setText('Prey') else -- Fallback to old method if miniwindowTitle doesn't exist preyTracker:setText('Prey') end local iconWidget = preyTracker:getChildById('miniwindowIcon') if iconWidget then iconWidget:setImageSource('/images/game/prey/icon-prey-widget') end -- Position lockButton where toggleFilterButton was (to the left of minimize button) local lockButton = preyTracker:recursiveGetChildById('lockButton') local minimizeButton = preyTracker:recursiveGetChildById('minimizeButton') if lockButton and minimizeButton then lockButton:breakAnchors() lockButton:addAnchor(AnchorTop, minimizeButton:getId(), AnchorTop) lockButton:addAnchor(AnchorRight, minimizeButton:getId(), AnchorLeft) lockButton:setMarginRight(7) -- Same margin as toggleFilterButton had lockButton:setMarginTop(0) end if g_game.isOnline() then check() end setUnsupportedSettings() end local pickSpecificPreyBonusBySlot = {} local pickSpecificPreyDescriptionDefault = 'If you like to select another prey creature, click here to choose from all available creatures.\nThe newly selected prey will be active for 2 hours hunting time again.\nYour current bonus will not be affected.' local pickSpecificPreyDescriptionTemplate = 'If you like to select another prey creature, click here to choose from all available creatures.\nThe newly selected prey will be active for 2 hours hunting time again.\nYour current bonus +%s%% %s will not be affected.' local descriptionTable = { ['shopPermButton'] = 'Go to the Store to purchase the Permanent Prey Slot. Once you have completed the purchase, you can activate a prey here, no matter if your character is on a free or a Premium account.', ['shopTempButton'] = 'You can activate this prey whenever your account has Premium Status.', ['preyWindow'] = '', ['noBonusIcon'] = 'This prey is not available for your character yet.\nCheck the large blue button(s) to learn how to unlock this prey slot', ['selectPrey'] = 'Click here to get a bonus with a higher value. The bonus for your prey will be selected randomly from one of the following: damage boost, damage reduction, bonus XP, improved loot. Your prey will be active for 2 hours hunting time again. Your prey creature will stay the same.', ['pickSpecificPrey'] = pickSpecificPreyDescriptionDefault, ['rerollButton'] = 'If you like to select another prey crature, click here to get a new list with 9 creatures to choose from.\nThe newly selected prey will be active for 2 hours hunting time again.', ['preyCandidate'] = 'Select a new prey creature for the next 2 hours hunting time.', ['choosePreyButton'] = 'Click on this button to confirm selected monsters as your prey creature for the next 2 hours hunting time.', ['automaticBonusReroll'] = 'Do you want to enable the Automatic Bonus Reroll?\nEach time the Automatic Bonus Reroll is triggered, 1 of your Prey Wildcards will be consumed.', ['preyLock'] = 'Do you want to enable the Lock Prey?\nEach time the Lock Prey is triggered, 5 of your Prey Wildcards will be consumed.' } local function getSlotIndexFromWidget(widget) while widget do local id = widget:getId() if id then local slotNumber = id:match('^slot(%d+)$') if slotNumber then return tonumber(slotNumber) - 1 end end widget = widget:getParent() end return nil end local function getPickSpecificPreyDescription(slot) local bonusInfo = pickSpecificPreyBonusBySlot[slot] if bonusInfo then local bonusName = getBonusDescription(bonusInfo.type) if bonusName then return string.format(pickSpecificPreyDescriptionTemplate, bonusInfo.value, bonusName) end end return pickSpecificPreyDescriptionDefault end local function setPickSpecificPreyBonus(slot, bonusType, bonusValue) if slot == nil then return end if bonusType and bonusType ~= PREY_BONUS_NONE and bonusValue ~= nil then pickSpecificPreyBonusBySlot[slot] = { type = bonusType, value = bonusValue } else pickSpecificPreyBonusBySlot[slot] = nil end end function onHover(widget) if type(widget) == 'string' then return preyWindow.description:setText(descriptionTable[widget]) elseif type(widget) == 'number' then local slot = 'slot' .. (widget + 1) local tracker = preyTracker.contentsPanel[slot] local desc = tracker.time:getTooltip() desc = desc:sub(1, desc:len() - 46) return preyWindow.description:setText(desc) end if widget and widget:isVisible() then local id = widget:getId() if id == 'pickSpecificPrey' then local slot = getSlotIndexFromWidget(widget) if slot then preyWindow.description:setText(getPickSpecificPreyDescription(slot)) return end end local desc = descriptionTable[id] if desc then preyWindow.description:setText(desc) end end end function terminate() disconnect(g_game, { onGameStart = check, onGameEnd = onGameEnd, onResourcesBalanceChange = Prey.onResourcesBalanceChange, onPreyFreeRerolls = onPreyFreeRerolls, onPreyTimeLeft = onPreyTimeLeft, onPreyRerollPrice = onPreyRerollPrice, onPreyLocked = onPreyLocked, onPreyInactive = onPreyInactive, onPreyActive = onPreyActive, onPreySelection = onPreySelection, onPreySelectionChangeMonster = onPreySelectionChangeMonster, onPreyListSelection = onPreyListSelection, onPreyWildcardSelection = onPreyWildcardSelection }) if preyButton then preyButton:destroy() end if preyTrackerButton then preyTrackerButton:destroy() end preyWindow:destroy() preyTracker:destroy() if msgWindow then msgWindow:destroy() msgWindow = nil end end local n = 0 function setUnsupportedSettings() local t = { 'slot1', 'slot2', 'slot3' } for i, slot in pairs(t) do local panel = preyWindow[slot] for j, state in pairs({ panel.active, panel.inactive }) do state.select.price.text:setText('5') end panel.active.autoRerollPrice.text:setText('1') panel.active.lockPreyPrice.text:setText('5') panel.active.choose.price.text:setText(1) end end function check() if g_game.getFeature(GamePrey) then if not preyButton then preyButton = modules.game_mainpanel.addToggleButton('preyButton', tr('Prey Dialog'), '/images/options/button_preydialog', toggle) end if g_game.getFeature(GameTaskboard) then if preyTrackerButton then preyTrackerButton:destroy() preyTrackerButton = nil end return end if not preyTrackerButton then preyTrackerButton = modules.game_mainpanel.addToggleButton('preyTrackerButton', tr('Prey Tracker'), '/images/options/button_prey', toggleTracker) end elseif preyButton then preyButton:destroy() preyButton = nil end end function toggleTracker() if preyTracker:isVisible() then preyTracker:hide() onMiniWindowClose() else if not preyTracker:getParent() then local panel = modules.game_interface.findContentPanelAvailable(preyTracker, preyTracker:getMinimumHeight()) if not panel then return end panel:addChild(preyTracker) end preyTracker:show() onMiniWindowOpen() end end local function resetPreyWindowState() if not preyWindow then return end preyWindow.description:setText('') preyWindow.gold:setText('0') preyWindow.wildCards:setText('0') for slot = 0, 2 do onPreyInactive(slot, 0, 0) local prey = preyWindow['slot' .. (slot + 1)] if prey then if prey.title then prey.title:setText('') end if prey.inactive and prey.inactive.list then prey.inactive.list:setVisible(true) prey.inactive.list:destroyChildren() end if prey.inactive then if prey.inactive.fullList then clearFullListEntries(prey.inactive.fullList) prey.inactive.fullList:setVisible(false) end if prey.inactive.preview then resetPreyPreviewWidget(prey.inactive.preview) prey.inactive.preview:setVisible(false) end if prey.inactive.select then prey.inactive.select:setVisible(true) end if prey.inactive.reroll then prey.inactive.reroll:setVisible(true) end end if prey.active and prey.active.creatureAndBonus then local creatureAndBonus = prey.active.creatureAndBonus if creatureAndBonus.timeLeft then creatureAndBonus.timeLeft:setPercent(0) creatureAndBonus.timeLeft:setText('') end if creatureAndBonus.bonus and creatureAndBonus.bonus.grade then creatureAndBonus.bonus.grade:destroyChildren() end end end end preyDescription = {} rerollPrice = 0 bonusRerolls = 0 bankGold = 0 inventoryGold = 0 raceEntriesBySlot = {} selectedRaceEntryBySlot = {} selectedRaceWidgetBySlot = {} end function onGameEnd() resetPreyWindowState() hide() end function hide() preyWindow:hide() if preyButton then preyButton:setOn(false) end if msgWindow then msgWindow:destroy() msgWindow = nil end end function show() if not g_game.getFeature(GamePrey) then return hide() end preyWindow:show() preyWindow:raise() preyWindow:focus() if preyButton then preyButton:setOn(true) end g_game.preyRequest() -- update preys, it's for tibia 12 end function toggle() if preyWindow:isVisible() then return hide() end show() end function onMiniWindowOpen() if preyTrackerButton then preyTrackerButton:setOn(true) end end function onMiniWindowClose() if preyTrackerButton then preyTrackerButton:setOn(false) end end function onPreyFreeRerolls(slot, timeleft) local prey = preyWindow['slot' .. (slot + 1)] local percent = (timeleft / (20 * 60)) * 100 local desc = timeleftTranslation(timeleft * 60) if not prey then return end for i, panel in pairs({ prey.active, prey.inactive }) do local progressBar = panel.reroll.button.time local price = panel.reroll.price.text progressBar:setPercent(percent) progressBar:setText(desc) if timeleft == 0 then price:setText('0') end end end function onPreyTimeLeft(slot, timeLeft) -- description preyDescription[slot] = preyDescription[slot] or { one = '', two = '' } local text = preyDescription[slot].one .. timeleftTranslation(timeLeft, true) .. preyDescription[slot].two -- tracker local percent = (timeLeft / (2 * 60 * 60)) * 100 slot = 'slot' .. (slot + 1) local tracker = preyTracker.contentsPanel[slot] tracker.time:setPercent(percent) tracker.time:setTooltip(text) for i, element in pairs({ tracker.creatureName, tracker.creature, tracker.preyType, tracker.time }) do element:setTooltip(text) element.onClick = function() show() end end -- main window local prey = preyWindow[slot] if not prey then return end local progressbar = prey.active.creatureAndBonus.timeLeft local desc = timeleftTranslation(timeLeft, true) progressbar:setPercent(percent) progressbar:setText(desc) end function onPreyRerollPrice(price) rerollPrice = price local t = { 'slot1', 'slot2', 'slot3' } for index, slot in ipairs(t) do local panel = preyWindow[slot] if panel then for j, state in pairs({ panel.active, panel.inactive }) do if state and state.reroll and state.reroll.price and state.reroll.button then local priceWidget = state.reroll.price.text local progressBar = state.reroll.button.time if progressBar:getText() ~= 'Free' then priceWidget:setText(comma_value(rerollPrice)) else priceWidget:setText('0') progressBar:setPercent(0) end end end end refreshRerollButtonState(index - 1) end end function setTimeUntilFreeReroll(slot, timeUntilFreeReroll) -- minutes local prey = preyWindow['slot' .. (slot + 1)] if not prey then return end local percent = (timeUntilFreeReroll / (20 * 60)) * 100 timeUntilFreeReroll = timeUntilFreeReroll > 720000 and 0 or timeUntilFreeReroll local desc = timeleftTranslation(timeUntilFreeReroll) for i, panel in pairs({ prey.active, prey.inactive }) do if panel and panel.reroll and panel.reroll.button and panel.reroll.price then local reroll = panel.reroll.button.time reroll:setPercent(percent) reroll:setText(desc) local price = panel.reroll.price.text if timeUntilFreeReroll > 0 then price:setText(comma_value(rerollPrice)) else price:setText('Free') end end end refreshRerollButtonState(slot) end function onPreyLocked(slot, unlockState, timeUntilFreeReroll, wildcards) setPickSpecificPreyBonus(slot) -- tracker slot = 'slot' .. (slot + 1) local tracker = preyTracker.contentsPanel[slot] if tracker then tracker:hide() preyTracker:setContentMaximumHeight(preyTracker:getHeight()) end -- main window local prey = preyWindow[slot] if not prey then return end prey.title:setText('Locked') prey.inactive:hide() prey.active:hide() prey.locked:show() end function onPreyInactive(slot, timeUntilFreeReroll, wildcards) -- tracker local tracker = preyTracker.contentsPanel['slot' .. (slot + 1)] if tracker then tracker.creature:hide() tracker.noCreature:show() tracker.creatureName:setText('Inactive') tracker.time:setPercent(0) tracker.preyType:setImageSource('/images/game/prey/prey_no_bonus') for i, element in pairs({ tracker.creatureName, tracker.creature, tracker.preyType, tracker.time }) do element:setTooltip('Inactive Prey. \n\nClick in this window to open the prey dialog.') element.onClick = function() show() end end end -- main window setTimeUntilFreeReroll(slot, timeUntilFreeReroll) local prey = preyWindow['slot' .. (slot + 1)] if not prey then return end prey.active:hide() prey.locked:hide() prey.inactive:show() setInactiveMode(slot, false, prey) raceEntriesBySlot[slot] = nil selectedRaceEntryBySlot[slot] = nil selectedRaceWidgetBySlot[slot] = nil local rerollButton = prey.inactive.reroll and prey.inactive.reroll.button and prey.inactive.reroll.button.rerollButton if rerollButton then rerollButton.onClick = function() showListRerollConfirmation(slot) end end setPickSpecificPreyBonus(slot) updatePickSpecificPreyButton(slot, wildcards) end function setBonusGradeStars(slot, grade) local prey = preyWindow['slot' .. (slot + 1)] local gradePanel = prey.active.creatureAndBonus.bonus.grade gradePanel:destroyChildren() for i = 1, 10 do if i <= grade then local widget = g_ui.createWidget('Star', gradePanel) widget.onHoverChange = function(widget, hovered) onHover(slot) end else local widget = g_ui.createWidget('NoStar', gradePanel) widget.onHoverChange = function(widget, hovered) onHover(slot) end end end end function getBigIconPath(bonusType) local path = '/images/game/prey/' if bonusType == PREY_BONUS_DAMAGE_BOOST then return path .. 'prey_bigdamage' elseif bonusType == PREY_BONUS_DAMAGE_REDUCTION then return path .. 'prey_bigdefense' elseif bonusType == PREY_BONUS_XP_BONUS then return path .. 'prey_bigxp' elseif bonusType == PREY_BONUS_IMPROVED_LOOT then return path .. 'prey_bigloot' end end function getSmallIconPath(bonusType) local path = '/images/game/prey/' if bonusType == PREY_BONUS_DAMAGE_BOOST then return path .. 'prey_damage' elseif bonusType == PREY_BONUS_DAMAGE_REDUCTION then return path .. 'prey_defense' elseif bonusType == PREY_BONUS_XP_BONUS then return path .. 'prey_xp' elseif bonusType == PREY_BONUS_IMPROVED_LOOT then return path .. 'prey_loot' end end function getBonusDescription(bonusType) if bonusType == PREY_BONUS_DAMAGE_BOOST then return 'Damage Boost' elseif bonusType == PREY_BONUS_DAMAGE_REDUCTION then return 'Damage Reduction' elseif bonusType == PREY_BONUS_XP_BONUS then return 'XP Bonus' elseif bonusType == PREY_BONUS_IMPROVED_LOOT then return 'Improved Loot' end end function getTooltipBonusDescription(bonusType, bonusValue) if bonusType == PREY_BONUS_DAMAGE_BOOST then return 'You deal +' .. bonusValue .. '% extra damage against your prey creature.' elseif bonusType == PREY_BONUS_DAMAGE_REDUCTION then return 'You take ' .. bonusValue .. '% less damage from your prey creature.' elseif bonusType == PREY_BONUS_XP_BONUS then return 'Killing your prey creature rewards +' .. bonusValue .. '% extra XP.' elseif bonusType == PREY_BONUS_IMPROVED_LOOT then return 'Your creature has a +' .. bonusValue .. '% chance to drop additional loot.' end end function capitalFormatStr(str) local formatted = '' str = string.split(str, ' ') for i, word in ipairs(str) do formatted = formatted .. ' ' .. (string.gsub(word, '^%l', string.upper)) end return formatted:trim() end local function getPreySlotWidget(slot) if not preyWindow then return nil end return preyWindow['slot' .. (slot + 1)] end local function setChoosePreyButtonEnabled(button, enabled) if not button then return end local imagePath if enabled then button:enable() imagePath = '/images/game/prey/prey_choose.png' else button:disable() imagePath = '/images/game/prey/prey_choose_blocked.png' end button:setImageSource(imagePath) end local function updateChoosePreyButtonState(slot) local prey = getPreySlotWidget(slot) if not prey or not prey.inactive or not prey.inactive.choose then return end local button = prey.inactive.choose.choosePreyButton if not button then return end local hasSelection = false local list = prey.inactive.list if list then for _, child in pairs(list:getChildren()) do if child.isChecked and child:isChecked() then hasSelection = true break end end end if not hasSelection and selectedRaceEntryBySlot[slot] then hasSelection = true end setChoosePreyButtonEnabled(button, hasSelection) end local function getWildcardCountOrDefault(wildcards) local playerBalance local player = g_game.getLocalPlayer() if player and ResourceTypes and ResourceTypes.PREY_WILDCARDS then playerBalance = player:getResourceBalance(ResourceTypes.PREY_WILDCARDS) end if type(wildcards) == 'number' then if playerBalance then return math.max(wildcards, playerBalance) end return wildcards end return playerBalance or 0 end local function showPreyConfirmationWindow(title, description, confirmAction) local confirmWindow local wasPreyWindowVisible = preyWindow and preyWindow:isVisible() local preyVisibilityRestored = false local function restorePreyWindowVisibility() if not preyVisibilityRestored and wasPreyWindowVisible and preyWindow then preyVisibilityRestored = true preyWindow:show() preyWindow:raise() preyWindow:focus() end end if wasPreyWindowVisible then preyWindow:hide() end local function closeWindow() if confirmWindow then confirmWindow:destroy() confirmWindow = nil restorePreyWindowVisibility() end end local function confirm() if confirmAction then confirmAction() end closeWindow() end confirmWindow = displayGeneralBox(tr(title), description, { { text = tr('No'), callback = closeWindow }, { text = tr('Yes'), callback = confirm }, }, confirm, closeWindow) if confirmWindow then confirmWindow.onDestroy = restorePreyWindowVisibility else restorePreyWindowVisibility() end end local function showPreyWildcardConfirmation(description, confirmAction) showPreyConfirmationWindow('Confirmation of Using Prey Wildcards', description, confirmAction) end local function showPickSpecificPreyConfirmation(slot, wildcardCount) local description = tr(string.format( 'Are you sure you want to use 5 of your remaining %s Prey Wildcards?', tostring(wildcardCount) )) showPreyWildcardConfirmation(description, function() g_game.preyAction(slot, PREY_ACTION_REQUEST_ALL_MONSTERS, 0) end) end local function showBonusRerollConfirmation(slot, wildcardCount) local description = tr(string.format( 'Are you sure you want to use 1 of your remaining %s Prey Wildcards?', tostring(wildcardCount) )) showPreyWildcardConfirmation(description, function() g_game.preyAction(slot, PREY_ACTION_BONUSREROLL, 0) end) end local function getPlayerTotalGold() local player = g_game.getLocalPlayer() if player and player.getTotalMoney then return player:getTotalMoney() end return (bankGold or 0) + (inventoryGold or 0) end local function getRerollPriceFromPanel(panel) if not panel or not panel.reroll or not panel.reroll.price then return nil end local priceWidget = panel.reroll.price.text if not priceWidget then return nil end local text = priceWidget:getText() if not text or text == '' then return nil end if text:lower() == 'free' then return 0 end local digits = text:gsub('[^%d]', '') if digits == '' then return nil end return tonumber(digits) end local function getDisplayedRerollPrice(slot) local prey = getPreySlotWidget(slot) if not prey then return rerollPrice end local function getPrice(panel, requireVisibility) if not panel then return nil end if requireVisibility and panel.isVisible and not panel:isVisible() then return nil end return getRerollPriceFromPanel(panel) end local price = getPrice(prey.active, true) or getPrice(prey.inactive, true) if price ~= nil then return price end price = getPrice(prey.active, false) or getPrice(prey.inactive, false) if price ~= nil then return price end return rerollPrice end function refreshRerollButtonState(slot) local prey = getPreySlotWidget(slot) if not prey then return end local totalGold = getPlayerTotalGold() local function updatePanel(panel) if not panel or not panel.reroll or not panel.reroll.button then return end local button = panel.reroll.button.rerollButton if not button then return end local price = getRerollPriceFromPanel(panel) if price == nil then price = rerollPrice end local isFree = price == nil or price <= 0 local canAfford = isFree or totalGold >= price if canAfford then button:setImageSource('/images/game/prey/prey_reroll') button:enable() else button:setImageSource('/images/game/prey/prey_reroll_blocked') button:disable() end end updatePanel(prey.active) updatePanel(prey.inactive) end local function showListRerollConfirmation(slot) local price = getDisplayedRerollPrice(slot) if price == nil then price = rerollPrice or 0 end if price <= 0 then g_game.preyAction(slot, PREY_ACTION_LISTREROLL, 0) return end local totalGold = getPlayerTotalGold() local description = tr(string.format( 'Do you want to spend %s gold for a List Reroll?\nYou current have %s gold available for the purchase.', comma_value(price), comma_value(totalGold) )) showPreyConfirmationWindow('Confirmation of Using List Reroll', description, function() g_game.preyAction(slot, PREY_ACTION_LISTREROLL, 0) end) end function updatePickSpecificPreyButton(slot, wildcards) local prey = getPreySlotWidget(slot) if not prey then return end local wildcardCount = getWildcardCountOrDefault(wildcards) local hasWildcardsAvailable = wildcardCount > 5 local function refreshButton(panel) if not panel or not panel.select or not panel.select.pickSpecificPrey then return end local button = panel.select.pickSpecificPrey button:setTooltip(getPickSpecificPreyDescription(slot)) if hasWildcardsAvailable then button:setImageSource('/images/game/prey/prey_select') button:enable() button.onClick = function() showPickSpecificPreyConfirmation(slot, wildcardCount) end else button:setImageSource('/images/game/prey/prey_select_blocked') button:disable() button.onClick = nil end end refreshButton(prey.active) refreshButton(prey.inactive) end function resetPreyPreviewWidget(preview) if not preview then return end if preview.placeholder then preview.placeholder:setVisible(true) end if preview.creature then preview.creature:setVisible(false) end end setWidgetTreePhantom = function(widget, phantom) if not widget or widget:isDestroyed() then return end widget:setPhantom(phantom) for _, child in pairs(widget:getChildren()) do setWidgetTreePhantom(child, phantom) end end function setInactiveMode(slot, showFullList, prey) prey = prey or getPreySlotWidget(slot) if not prey or not prey.inactive then return prey end local inactive = prey.inactive if inactive.list then inactive.list:setVisible(not showFullList) setWidgetTreePhantom(inactive.list, showFullList) end if inactive.fullList then inactive.fullList:setVisible(showFullList) end if inactive.preview then inactive.preview:setVisible(showFullList) if not showFullList or not selectedRaceEntryBySlot[slot] then resetPreyPreviewWidget(inactive.preview) end end if inactive.select then inactive.select:setVisible(not showFullList) end if inactive.reroll then inactive.reroll:setVisible(not showFullList) end return prey end local function isDescendantOf(widget, ancestor) if not widget or not ancestor then return false end local current = widget while current do if current == ancestor then return true end current = current:getParent() end return false end local function getFullListEntriesContainer(fullList) if not fullList then return nil end local entries = fullList.entries if not entries then return nil end if entries.entriesContainer then return entries.entriesContainer end if entries.getChildById then local contents = entries:getChildById('entriesContainer') or entries:getChildById('contentsPanel') if contents then entries.entriesContainer = contents return contents end end entries.entriesContainer = entries return entries end function clearFullListEntries(fullList) local container = getFullListEntriesContainer(fullList) if container then container:destroyChildren() end if fullList and fullList.entries and fullList.entries.verticalScrollBar then local scrollbar = fullList.entries.verticalScrollBar if scrollbar.getMinimum and scrollbar.setValue then scrollbar:setValue(scrollbar:getMinimum()) end end end local suppressSearchTextHandler = false local function setSearchTextSilently(widget, text) if not widget or widget:getText() == text then return end suppressSearchTextHandler = true widget:setText(text) suppressSearchTextHandler = false end local function updateRaceSearchClearButton(slot) local prey = getPreySlotWidget(slot) if not prey or not prey.inactive or not prey.inactive.fullList then return end local fullList = prey.inactive.fullList local clearButton = fullList.searchClearButton if not clearButton then return end local text = raceSearchTextsBySlot[slot] clearButton:setVisible(text and text:len() > 0) end local function updateRaceSearchUI(slot) local prey = getPreySlotWidget(slot) if not prey or not prey.inactive or not prey.inactive.fullList then return end local fullList = prey.inactive.fullList local searchEdit = fullList.searchEdit local clearButton = fullList.searchClearButton local text = raceSearchTextsBySlot[slot] or '' if searchEdit then searchEdit.preySlot = slot setSearchTextSilently(searchEdit, text) searchEdit:setCursorPos(-1) end if clearButton then clearButton.preySlot = slot clearButton.searchEdit = searchEdit end updateRaceSearchClearButton(slot) end local function uncheckChildrenExcept(parent, except) if not parent then return end for _, child in pairs(parent:getChildren()) do if child ~= except and child.setChecked then if not child:isDestroyed() then child:setChecked(false) restoreRaceListItemBackground(child) end end uncheckChildrenExcept(child, except) end end function onItemBoxChecked(widget) for _, slotId in ipairs({ 'slot1', 'slot2', 'slot3' }) do local slotWidget = preyWindow[slotId] if slotWidget and slotWidget.inactive then local list = slotWidget.inactive.list if list and isDescendantOf(widget, list) then uncheckChildrenExcept(list, widget) widget:setChecked(true) local slotIndex = tonumber(slotId:match('slot(%d+)')) if slotIndex then updateChoosePreyButtonState(slotIndex - 1) end return end local fullList = slotWidget.inactive.fullList if fullList then local entriesContainer = getFullListEntriesContainer(fullList) or fullList if entriesContainer and isDescendantOf(widget, entriesContainer) then uncheckChildrenExcept(entriesContainer, widget) widget:setChecked(true) local slotIndex = tonumber(slotId:match('slot(%d+)')) if slotIndex then updateChoosePreyButtonState(slotIndex - 1) end return end end end end widget:setChecked(true) end local function setWidgetTextToFit(widget, text, formatter) if not widget then return '' end text = text or '' formatter = formatter or function(value) return value end local ellipsis = '...' local paddingLeft = widget.getPaddingLeft and widget:getPaddingLeft() or 0 local paddingRight = widget.getPaddingRight and widget:getPaddingRight() or 0 local availableWidth = widget:getWidth() - paddingLeft - paddingRight if availableWidth <= 0 then local formatted = formatter(text) widget:setText(formatted) return formatted end local function setAndCheck(value) local formattedValue = formatter(value) widget:setText(formattedValue) local textSize = widget:getTextSize() return textSize.width <= availableWidth, formattedValue end local fits, formatted = setAndCheck(text) if fits then return formatted end local bestFormatted local left, right = 0, #text while left <= right do local mid = math.floor((left + right) / 2) local candidate = text:sub(1, mid) .. ellipsis local candidateFits, candidateFormatted = setAndCheck(candidate) if candidateFits then bestFormatted = candidateFormatted left = mid + 1 else right = mid - 1 end end if bestFormatted then widget:setText(bestFormatted) return bestFormatted end local _, ellipsisFormatted = setAndCheck(ellipsis) widget:setText(ellipsisFormatted) return ellipsisFormatted end local function buildRaceEntry(raceId) local raceData = g_things.getRaceData(raceId) local name = raceData and raceData.name or nil if name and name ~= '' then name = capitalFormatStr(name) else name = tr('Unknown Creature (%d)', raceId) end local outfit = raceData and raceData.outfit or nil local realSize if outfit and outfit.type then local creatureType = g_things.getThingType(outfit.type, ThingCategoryCreature) realSize = creatureType and creatureType:getRealSize() or nil end return { raceId = raceId, name = name, searchName = name:lower(), outfit = outfit, realSize = realSize } end restoreRaceListItemBackground = function(widget) if not widget or widget:isDestroyed() then return end if widget:isChecked() then if widget.checkedBackground then widget:setBackgroundColor(widget.checkedBackground) end if widget.checkedTextColor then widget:setColor(widget.checkedTextColor) end return end if widget.baseBackground then widget:setBackgroundColor(widget.baseBackground) end if widget.baseTextColor then widget:setColor(widget.baseTextColor) end end updateRaceSelectionDisplay = function(slot) local prey = getPreySlotWidget(slot) if not prey or not prey.inactive or not prey.inactive.fullList then return end local entry = selectedRaceEntryBySlot[slot] if prey.title then if entry then setWidgetTextToFit(prey.title, entry.name, function(value) return tr('Selected: %s', value) end) else prey.title:setText(tr('Select your prey creature')) end end local preview = prey.inactive and prey.inactive.preview if preview then local creatureWidget = preview.creature local placeholder = preview.placeholder if entry and entry.outfit and creatureWidget then local spriteSize = g_gameConfig.getSpriteSize() if spriteSize <= 0 then spriteSize = 32 end local widgetSize = math.min(creatureWidget:getWidth(), creatureWidget:getHeight()) local referenceSize = math.max(entry.realSize or spriteSize * 2, spriteSize * 2) local targetSize = widgetSize > 0 and widgetSize or spriteSize * 2 local scale = math.floor((targetSize / referenceSize) * 100) if scale < 1 then scale = 1 elseif scale > 100 then scale = 100 end creatureWidget:setCreatureSize(size) creatureWidget:setOutfit(entry.outfit) creatureWidget:setVisible(true) if placeholder then placeholder:setVisible(false) end else if creatureWidget then creatureWidget:setVisible(false) end if placeholder then placeholder:setVisible(true) end end end local chooseButton = prey.inactive.choose and prey.inactive.choose.choosePreyButton if chooseButton then setChoosePreyButtonEnabled(chooseButton, entry ~= nil) end end setRaceSelection = function(slot, widget, skipUncheck) local previousWidget = selectedRaceWidgetBySlot[slot] if widget and widget:isDestroyed() then widget = nil end if widget and not skipUncheck then onItemBoxChecked(widget) elseif not widget and previousWidget and not previousWidget:isDestroyed() and previousWidget.setChecked then previousWidget:setChecked(false) restoreRaceListItemBackground(previousWidget) elseif widget and skipUncheck then if previousWidget and previousWidget ~= widget and not previousWidget:isDestroyed() and previousWidget.setChecked then previousWidget:setChecked(false) restoreRaceListItemBackground(previousWidget) end if not widget:isChecked() then widget:setChecked(true) end end if previousWidget and previousWidget ~= widget then restoreRaceListItemBackground(previousWidget) end selectedRaceWidgetBySlot[slot] = widget selectedRaceEntryBySlot[slot] = widget and widget.raceData or nil if widget then restoreRaceListItemBackground(widget) end updateRaceSelectionDisplay(slot) updateChoosePreyButtonState(slot) end refreshRaceList = function(slot) local prey = getPreySlotWidget(slot) if not prey or not prey.inactive or not prey.inactive.fullList then return end local fullList = prey.inactive.fullList clearFullListEntries(fullList) local entriesPanel = getFullListEntriesContainer(fullList) if not entriesPanel then return end local currentSelectionId = selectedRaceEntryBySlot[slot] and selectedRaceEntryBySlot[slot].raceId or nil local selectionRestored = false local backgroundA = '#484848' local backgroundB = '#414141' local useAlternate = false local searchFilter = raceSearchTextsBySlot[slot] if searchFilter and searchFilter:len() > 0 then searchFilter = searchFilter:lower() else searchFilter = nil end for _, entry in ipairs(raceEntriesBySlot[slot] or {}) do if not searchFilter or (entry.searchName and entry.searchName:find(searchFilter, 1, true)) then local item = g_ui.createWidget('PreyCreatureListItem', entriesPanel) setWidgetTextToFit(item, entry.name) item:setTooltip(entry.name) item.raceData = entry item.preySlot = slot item.baseBackground = useAlternate and backgroundB or backgroundA item.checkedBackground = '#585858' item.baseTextColor = '#c0c0c0' item.checkedTextColor = '#ffffff' item:setBackgroundColor(item.baseBackground) item:setColor(item.baseTextColor) item.onCheckChange = function(widget) restoreRaceListItemBackground(widget) end restoreRaceListItemBackground(item) useAlternate = not useAlternate if currentSelectionId and entry.raceId == currentSelectionId then setRaceSelection(slot, item, true) selectionRestored = true end end end if not selectionRestored and currentSelectionId then setRaceSelection(slot, nil, true) elseif not currentSelectionId then updateRaceSelectionDisplay(slot) end updateChoosePreyButtonState(slot) end function onRaceSearchTextChanged(widget) if not widget or not widget.preySlot then return end if suppressSearchTextHandler then updateRaceSearchClearButton(widget.preySlot) return end local slot = widget.preySlot local text = widget:getText() or '' local trimmed = text:trim() if text ~= trimmed then setSearchTextSilently(widget, trimmed) widget:setCursorPos(-1) text = trimmed end if trimmed:len() == 0 then raceSearchTextsBySlot[slot] = nil else raceSearchTextsBySlot[slot] = trimmed end updateRaceSearchClearButton(slot) refreshRaceList(slot) end function onRaceSearchClearClicked(widget) if not widget or not widget.preySlot then return end local slot = widget.preySlot local searchEdit = widget.searchEdit if not searchEdit or searchEdit:isDestroyed() then local prey = getPreySlotWidget(slot) if prey and prey.inactive and prey.inactive.fullList then searchEdit = prey.inactive.fullList.searchEdit end end raceSearchTextsBySlot[slot] = nil if searchEdit and not searchEdit:isDestroyed() then setSearchTextSilently(searchEdit, '') searchEdit:setCursorPos(0) end updateRaceSearchClearButton(slot) refreshRaceList(slot) end function onPreyRaceListItemClicked(widget) if not widget or not widget.preySlot then return end setRaceSelection(widget.preySlot, widget, false) end function onPreyRaceListItemHoverChange(widget, hovered) if not widget or widget:isDestroyed() then return end restoreRaceListItemBackground(widget) end local suppressOptionCheckHandler = false local function setOptionCheckedSilently(checkbox, checked) if checkbox:isChecked() == checked then return end suppressOptionCheckHandler = true checkbox:setChecked(checked) suppressOptionCheckHandler = false end local function getToggleCheckboxes(slot) local prey = preyWindow and preyWindow['slot' .. (slot + 1)] if not prey or not prey.active then return nil, nil end local autoCheckbox = prey.active.autoReroll and prey.active.autoReroll.autoRerollCheck local lockCheckbox = prey.active.lockPrey and prey.active.lockPrey.lockPreyCheck return autoCheckbox, lockCheckbox end local function sendOption(slot, option) g_game.preyAction(slot, PREY_ACTION_OPTION, option) end local function handleToggleOptions(checkbox, slot, currentOption, checked) if suppressOptionCheckHandler then return end local autoCheckbox, lockCheckbox = getToggleCheckboxes(slot) local otherCheckbox = currentOption == PREY_OPTION_TOGGLE_AUTOREROLL and lockCheckbox or autoCheckbox if checked then local confirmWindow local wasPreyWindowVisible = preyWindow and preyWindow:isVisible() local preyVisibilityRestored = false local function restorePreyWindowVisibility() if not preyVisibilityRestored and wasPreyWindowVisible and preyWindow then preyVisibilityRestored = true preyWindow:show() preyWindow:raise() preyWindow:focus() end end if wasPreyWindowVisible then preyWindow:hide() end local function closeWindow() if confirmWindow then confirmWindow:destroy() confirmWindow = nil restorePreyWindowVisibility() end end local function confirm() if otherCheckbox and otherCheckbox:isChecked() then setOptionCheckedSilently(otherCheckbox, false) sendOption(slot, PREY_OPTION_UNTOGGLE) end setOptionCheckedSilently(checkbox, true) sendOption(slot, currentOption) closeWindow() end local function cancel() setOptionCheckedSilently(checkbox, false) closeWindow() end local description = currentOption == PREY_OPTION_TOGGLE_AUTOREROLL and tr(descriptionTable['automaticBonusReroll']) or tr(descriptionTable['preyLock']) confirmWindow = displayGeneralBox(tr('Confirmation of Using Prey Wildcards'), description, { { text = tr('No'), callback = cancel }, { text = tr('Yes'), callback = confirm }, }, confirm, cancel) if confirmWindow then confirmWindow.onDestroy = restorePreyWindowVisibility end return end sendOption(slot, PREY_OPTION_UNTOGGLE) end function onPreyActive(slot, currentHolderName, currentHolderOutfit, bonusType, bonusValue, bonusGrade, timeLeft, timeUntilFreeReroll, wildcards, option) -- locktype always 0 for protocols <12 local tracker = preyTracker.contentsPanel['slot' .. (slot + 1)] currentHolderName = capitalFormatStr(currentHolderName) local percent = (timeLeft / (2 * 60 * 60)) * 100 if tracker then tracker.creature:show() tracker.noCreature:hide() tracker.creatureName:setText(currentHolderName) tracker.creature:setOutfit(currentHolderOutfit) tracker.preyType:setImageSource(getSmallIconPath(bonusType)) tracker.time:setPercent(percent) preyDescription[slot] = preyDescription[slot] or {} preyDescription[slot].one = 'Creature: ' .. currentHolderName .. '\nDuration: ' preyDescription[slot].two = '\nValue: ' .. bonusGrade .. '/10' .. '\nType: ' .. getBonusDescription(bonusType) .. '\n' .. getTooltipBonusDescription(bonusType, bonusValue) .. '\n\nClick in this window to open the prey dialog.' for i, element in pairs({ tracker.creatureName, tracker.creature, tracker.preyType, tracker.time }) do element:setTooltip(preyDescription[slot].one .. timeleftTranslation(timeLeft, true) .. preyDescription[slot].two) element.onClick = function() show() end end end local prey = preyWindow['slot' .. (slot + 1)] if not prey then return end prey.inactive:hide() prey.locked:hide() prey.active:show() prey.title:setText(currentHolderName) local creatureAndBonus = prey.active.creatureAndBonus creatureAndBonus.creature:setOutfit(currentHolderOutfit) setTimeUntilFreeReroll(slot, timeUntilFreeReroll) creatureAndBonus.bonus.icon:setImageSource(getBigIconPath(bonusType)) creatureAndBonus.bonus.icon.onHoverChange = function(widget, hovered) onHover(slot) end setBonusGradeStars(slot, bonusGrade) creatureAndBonus.timeLeft:setPercent(percent) creatureAndBonus.timeLeft:setText(timeleftTranslation(timeLeft)) -- bonus reroll local wildcardCount = getWildcardCountOrDefault(wildcards) setPickSpecificPreyBonus(slot, bonusType, bonusValue) prey.active.choose.selectPrey.onClick = function() showBonusRerollConfirmation(slot, wildcardCount) end -- creature reroll prey.active.reroll.button.rerollButton.onClick = function() showListRerollConfirmation(slot) end setOptionCheckedSilently(prey.active.autoReroll.autoRerollCheck, option == PREY_OPTION_TOGGLE_AUTOREROLL) prey.active.autoReroll.autoRerollCheck.onCheckChange = function(widget, checked) handleToggleOptions(widget, slot, PREY_OPTION_TOGGLE_AUTOREROLL, checked) end setOptionCheckedSilently(prey.active.lockPrey.lockPreyCheck, option == PREY_OPTION_TOGGLE_LOCK_PREY) prey.active.lockPrey.lockPreyCheck.onCheckChange = function(widget, checked) handleToggleOptions(widget, slot, PREY_OPTION_TOGGLE_LOCK_PREY, checked) end updatePickSpecificPreyButton(slot, wildcards) end function onPreySelection(slot, names, outfits, timeUntilFreeReroll, wildcards, option) -- tracker local tracker = preyTracker.contentsPanel['slot' .. (slot + 1)] if tracker then tracker.creature:hide() tracker.noCreature:show() tracker.creatureName:setText('Inactive') tracker.time:setPercent(0) tracker.preyType:setImageSource('/images/game/prey/prey_no_bonus') for i, element in pairs({ tracker.creatureName, tracker.creature, tracker.preyType, tracker.time }) do element:setTooltip('Inactive Prey. \n\nClick in this window to open the prey dialog.') element.onClick = function() show() end end end -- main window local prey = preyWindow['slot' .. (slot + 1)] setTimeUntilFreeReroll(slot, timeUntilFreeReroll) if not prey then return end prey.active:hide() prey.locked:hide() prey.inactive:show() setInactiveMode(slot, false, prey) raceEntriesBySlot[slot] = nil selectedRaceEntryBySlot[slot] = nil selectedRaceWidgetBySlot[slot] = nil setPickSpecificPreyBonus(slot) prey.title:setText(tr('Select monster')) local rerollButton = prey.inactive.reroll and prey.inactive.reroll.button and prey.inactive.reroll.button.rerollButton if rerollButton then rerollButton.onClick = function() showListRerollConfirmation(slot) end end local list = prey.inactive.list list:destroyChildren() for i, name in ipairs(names) do local box = g_ui.createWidget('PreyCreatureBox', list) name = capitalFormatStr(name) box:setTooltip(name) box.creature:setOutfit(outfits[i]) local backgroundColor = (i % 2 == 1) and '#484848' or '#414141' box:setBackgroundColor(backgroundColor) end prey.inactive.choose.choosePreyButton.onClick = function() for i, child in pairs(list:getChildren()) do if child:isChecked() then return g_game.preyAction(slot, PREY_ACTION_MONSTERSELECTION, i - 1) end end return showMessage(tr('Error'), tr('Select monster to proceed.')) end updateChoosePreyButtonState(slot) updatePickSpecificPreyButton(slot, wildcards) end function onPreySelectionChangeMonster(slot, names, outfits, bonusType, bonusValue, bonusGrade, timeUntilFreeReroll, wildcards, option) -- tracker local tracker = preyTracker.contentsPanel['slot' .. (slot + 1)] if tracker then tracker.creature:hide() tracker.noCreature:show() tracker.creatureName:setText('Inactive') tracker.time:setPercent(0) tracker.preyType:setImageSource('/images/game/prey/prey_no_bonus') for i, element in pairs({ tracker.creatureName, tracker.creature, tracker.preyType, tracker.time }) do element:setTooltip('Inactive Prey. \n\nClick in this window to open the prey dialog.') element.onClick = function() show() end end end -- main window local prey = preyWindow['slot' .. (slot + 1)] setTimeUntilFreeReroll(slot, timeUntilFreeReroll) if not prey then return end prey.active:hide() prey.locked:hide() prey.inactive:show() setInactiveMode(slot, false, prey) raceEntriesBySlot[slot] = nil selectedRaceEntryBySlot[slot] = nil selectedRaceWidgetBySlot[slot] = nil setPickSpecificPreyBonus(slot) prey.title:setText(tr('Select monster')) local rerollButton = prey.inactive.reroll and prey.inactive.reroll.button and prey.inactive.reroll.button.rerollButton if rerollButton then rerollButton.onClick = function() showListRerollConfirmation(slot) end end local list = prey.inactive.list list:destroyChildren() for i, name in ipairs(names) do local box = g_ui.createWidget('PreyCreatureBox', list) name = capitalFormatStr(name) box:setTooltip(name) box.creature:setOutfit(outfits[i]) local backgroundColor = (i % 2 == 1) and '#484848' or '#414141' box:setBackgroundColor(backgroundColor) end prey.inactive.choose.choosePreyButton.onClick = function() for i, child in pairs(list:getChildren()) do if child:isChecked() then return g_game.preyAction(slot, PREY_ACTION_MONSTERSELECTION, i - 1) end end return showMessage(tr('Error'), tr('Select monster to proceed.')) end updateChoosePreyButtonState(slot) updatePickSpecificPreyButton(slot, wildcards) end function onPreyListSelection(slot, races, nextFreeReroll, wildcards, option) setTimeUntilFreeReroll(slot, nextFreeReroll) local prey = getPreySlotWidget(slot) if not prey then return end prey.active:hide() prey.locked:hide() prey.inactive:show() setPickSpecificPreyBonus(slot) selectedRaceEntryBySlot[slot] = nil selectedRaceWidgetBySlot[slot] = nil setInactiveMode(slot, true, prey) local fullList = prey.inactive.fullList if not fullList then return end prey.title:setText(tr('Select your prey creature')) clearFullListEntries(fullList) local preview = prey.inactive.preview if preview then resetPreyPreviewWidget(preview) end raceEntriesBySlot[slot] = {} for _, raceId in ipairs(races) do table.insert(raceEntriesBySlot[slot], buildRaceEntry(raceId)) end table.sort(raceEntriesBySlot[slot], function(a, b) return a.name < b.name end) raceSearchTextsBySlot[slot] = nil updateRaceSearchUI(slot) local chooseButton = prey.inactive.choose and prey.inactive.choose.choosePreyButton if chooseButton then setChoosePreyButtonEnabled(chooseButton, false) chooseButton.onClick = function() local selected = selectedRaceEntryBySlot[slot] if not selected then return showMessage(tr('Error'), tr('Select monster to proceed.')) end g_game.preyAction(slot, PREY_ACTION_CHANGE_FROM_ALL, selected.raceId) end end refreshRaceList(slot) updateChoosePreyButtonState(slot) local rerollButton = prey.inactive.reroll and prey.inactive.reroll.button and prey.inactive.reroll.button.rerollButton if rerollButton then rerollButton.onClick = function() showListRerollConfirmation(slot) end end updateChoosePreyButtonState(slot) updatePickSpecificPreyButton(slot, wildcards) end function onPreyWildcardSelection(slot, races, nextFreeReroll, wildcards, option) updatePickSpecificPreyButton(slot, wildcards) end function Prey.onResourcesBalanceChange(balance, oldBalance, type) if type == ResourceTypes.BANK_BALANCE then -- bank gold bankGold = balance elseif type == ResourceTypes.GOLD_EQUIPPED then -- inventory gold inventoryGold = balance elseif type == ResourceTypes.PREY_WILDCARDS then -- bonus rerolls bonusRerolls = balance for slot = 0, 2 do updatePickSpecificPreyButton(slot, balance) end end local player = g_game.getLocalPlayer() g_logger.debug('' .. tostring(type) .. ', ' .. tostring(balance)) if player then preyWindow.wildCards:setText(tostring(player:getResourceBalance(ResourceTypes.PREY_WILDCARDS))) preyWindow.gold:setText(comma_value(player:getTotalMoney())) end if type == ResourceTypes.BANK_BALANCE or type == ResourceTypes.GOLD_EQUIPPED then for slot = 0, 2 do refreshRerollButtonState(slot) end end end function showMessage(title, message) if msgWindow then msgWindow:destroy() end msgWindow = displayInfoBox(title, message) msgWindow:show() msgWindow:raise() msgWindow:focus() end