-- sponsored by kivera-global.com -- remade by Vithrax#5814 local preyWindow local preyButton local preyTracker 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_LOCK_PREY = 5 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)" elseif bonusType == PREY_BONUS_DAMAGE_BOOST then return "-" end return "Uknown 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 = hide, onResourceBalance = onResourceBalance, onPreyFreeRolls = onPreyFreeRolls, onPreyTimeLeft = onPreyTimeLeft, onPreyPrice = onPreyPrice, onPreyLocked = onPreyLocked, onPreyInactive = onPreyInactive, onPreyActive = onPreyActive, onPreySelection = onPreySelection }) preyWindow = g_ui.displayUI('prey') preyWindow:hide() preyTracker = g_ui.createWidget('PreyTracker', modules.game_interface.getRightPanel()) preyTracker:setup() preyTracker:setContentMaximumHeight(100) preyTracker:setContentMinimumHeight(47) preyTracker:hide() if g_game.isOnline() then check() end setUnsupportedSettings() end 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"] = "Available only for protocols 12+", ["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." } 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:isVisible() then local id = widget:getId() local desc = descriptionTable[id] if desc then preyWindow.description:setText(desc) end end end function terminate() disconnect(g_game, { onGameStart = check, onGameEnd = hide, onResourceBalance = onResourceBalance, onPreyFreeRolls = onPreyFreeRolls, onPreyTimeLeft = onPreyTimeLeft, onPreyPrice = onPreyPrice, onPreyLocked = onPreyLocked, onPreyInactive = onPreyInactive, onPreyActive = onPreyActive, onPreySelection = onPreySelection }) 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 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("-------") end panel.active.autoRerollPrice.text:setText("-") panel.active.lockPreyPrice.text:setText("-") panel.active.choose.price.text:setText(1) panel.active.autoReroll.autoRerollCheck:disable() panel.active.lockPrey.lockPreyCheck:disable() end end function check() if g_game.getFeature(GamePrey) then if not preyButton then preyButton = modules.client_topmenu.addRightGameToggleButton('preyButton', tr('Prey Dialog'), '/images/topbuttons/prey_window', toggle) end if not preyTrackerButton then preyTrackerButton = modules.client_topmenu.addRightGameToggleButton("preyTrackerButton", tr('Prey Tracker'), '/images/topbuttons/prey', toggleTracker) end elseif preyButton then preyButton:destroy() preyButton = nil end end function toggleTracker() if preyTracker:isVisible() then preyTracker:hide() else preyTracker:show() end end function hide() preyWindow:hide() 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() --g_game.preyRequest() -- update preys, it's for tibia 12 end function toggle() if preyWindow:isVisible() then return hide() end show() end function onPreyFreeRolls(slot, timeleft) local prey = preyWindow["slot" .. (slot + 1)] local percent = (timeleft / 2 * 60 * 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("Free") end end end local regex = [[Duration: ([^m]+)]] function onPreyTimeLeft(slot, timeleft) -- tracker local percent = (timeleft / (2 * 60 * 60)) * 100 slot = "slot" .. (slot + 1) local tracker = preyTracker.contentsPanel[slot] tracker.time:setPercent(percent) local text = tracker.time:getTooltip() local re = regexMatch(text, regex) local oldTime = re[1][2] local newTime = timeleftTranslation(timeleft, true) newTime = newTime:sub(1,newTime:len()-1) text = text:gsub(oldTime, newTime) 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 onPreyPrice(price) rerollPrice = price 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 local price = state.reroll.price.text local progressBar = state.reroll.button.time if progressBar:getText() ~= "Free" then price:setText(comma_value(rerollPrice)) else price:setText("0") progressBar:setPercent(0) end end 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 local desc = timeleftTranslation(timeUntilFreeReroll * 60) for i, panel in pairs({prey.active, prey.inactive}) do 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 function onPreyLocked(slot, unlockState, timeUntilFreeReroll) -- tracker slot = "slot" .. (slot + 1) local tracker = preyTracker.contentsPanel[slot] if tracker then tracker:hide() preyTracker:setContentMaximumHeight(preyTracker:getHeight()-20) 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) -- 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() local rerollButton = prey.inactive.reroll.button.rerollButton rerollButton:setImageSource("/images/game/prey/prey_reroll_blocked") rerollButton:disable() rerollButton.onClick = function() g_game.preyAction(slot, PREY_ACTION_LISTREROLL, 0) end 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 function onItemBoxChecked(widget) for i, slot in pairs({"slot1", "slot2", "slot3"}) do local list = preyWindow[slot].inactive.list:getChildren() if table.find(list, widget) then for i, child in pairs(list) do if child ~= widget then child:setChecked(false) end end end end widget:setChecked(true) end function onPreyActive(slot, currentHolderName, currentHolderOutfit, bonusType, bonusValue, bonusGrade, timeLeft, timeUntilFreeReroll) 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) for i, element in pairs({tracker.creatureName, tracker.creature, tracker.preyType, tracker.time}) do element:setTooltip("Creature: "..currentHolderName .. "\nDuration: ".. timeleftTranslation(timeLeft, true) .."\nValue: " ..bonusGrade.."/10".."\nType: " .. getBonusDescription(bonusType) .. "\n"..getTooltipBonusDescription(bonusType,bonusValue).."\n\nClick in this window to open the prey dialog.") 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 prey.active.choose.selectPrey.onClick = function() g_game.preyAction(slot, PREY_ACTION_BONUSREROLL, 0) end -- creature reroll prey.active.reroll.button.rerollButton.onClick = function() g_game.preyAction(slot, PREY_ACTION_LISTREROLL, 0) end end function onPreySelection(slot, bonusType, bonusValue, bonusGrade, names, outfits, timeUntilFreeReroll) -- 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() prey.title:setText(tr("Select monster")) local rerollButton = prey.inactive.reroll.button.rerollButton rerollButton:setImageSource("/images/game/prey/prey_reroll_blocked") rerollButton:disable() 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]) box.onHoverChange = function(widget, hovered) onHover("preyCandidate") end 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 end function onResourceBalance(type, balance) if type == 0 then -- bank gold bankGold = balance elseif type == 1 then -- inventory gold inventoryGold = balance elseif type == 10 then -- bonus rerolls bonusRerolls = balance preyWindow.wildCards:setText(balance) end if type == 0 or type == 1 then preyWindow.gold:setText(comma_value(bankGold + inventoryGold)) end end function showMessage(title, message) if msgWindow then msgWindow:destroy() end msgWindow = displayInfoBox(title, message) msgWindow:show() msgWindow:raise() msgWindow:focus() end