diff --git a/modules/game_bot/bot.lua b/modules/game_bot/bot.lua index 9431394..04d6e55 100644 --- a/modules/game_bot/bot.lua +++ b/modules/game_bot/bot.lua @@ -477,6 +477,7 @@ function initCallbacks() onChannelEvent = botChannelEvent, onImbuementWindow = botOnImbuementWindow, onModalDialog = botOnModalDialog, + onAttackingCreatureChange = botOnAttackingCreatureChange }) connect(Tile, { @@ -532,6 +533,7 @@ function terminateCallbacks() onChannelEvent = botChannelEvent, onImbuementWindow = botOnImbuementWindow, onModalDialog = botOnModalDialog, + onAttackingCreatureChange = botOnAttackingCreatureChange }) disconnect(Tile, { @@ -717,3 +719,8 @@ function botOnModalDialog(id, title, message, buttons, enterButton, escapeButton if botExecutor == nil then return false end safeBotCall(function() botExecutor.callbacks.onModalDialog(id, title, message, buttons, enterButton, escapeButton, choices, priority) end) end + +function botOnAttackingCreatureChange(creature, oldCreature) + if botExecutor == nil then return false end + safeBotCall(function() botExecutor.callbacks.onAttackingCreatureChange(creature,oldCreature) end) +end \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/1_pushmax.lua b/modules/game_bot/default_configs/vBot/1_pushmax.lua deleted file mode 100644 index 9fc9cf5..0000000 --- a/modules/game_bot/default_configs/vBot/1_pushmax.lua +++ /dev/null @@ -1,187 +0,0 @@ -setDefaultTab("Main") - -pushPanelName = "pushmax" -local ui = setupUI([[ -Panel - height: 19 - - BotSwitch - id: title - anchors.top: parent.top - anchors.left: parent.left - text-align: center - width: 130 - !text: tr('PUSHMAX') - - Button - id: push - anchors.top: prev.top - anchors.left: prev.right - anchors.right: parent.right - margin-left: 3 - height: 17 - text: Setup - -]]) -ui:setId(pushPanelName) - -if not storage[pushPanelName] then - storage[pushPanelName] = { - enabled = true, - pushDelay = 1060, - pushMaxRuneId = 3188, - mwallBlockId = 2128, - pushMaxKey = "PageUp" - } -end - -ui.title:setOn(storage[pushPanelName].enabled) -ui.title.onClick = function(widget) -storage[pushPanelName].enabled = not storage[pushPanelName].enabled -widget:setOn(storage[pushPanelName].enabled) -end - -ui.push.onClick = function(widget) - pushWindow:show() - pushWindow:raise() - pushWindow:focus() -end - -rootWidget = g_ui.getRootWidget() -if rootWidget then - pushWindow = g_ui.createWidget('PushMaxWindow', rootWidget) - pushWindow:hide() - - pushWindow.closeButton.onClick = function(widget) - pushWindow:hide() - end - - local updateDelayText = function() - pushWindow.delayText:setText("Push Delay: ".. storage[pushPanelName].pushDelay) - end - updateDelayText() - pushWindow.delay.onValueChange = function(scroll, value) - storage[pushPanelName].pushDelay = value - updateDelayText() - end - pushWindow.delay:setValue(storage[pushPanelName].pushDelay) - - pushWindow.runeId.onItemChange = function(widget) - storage[pushPanelName].pushMaxRuneId = widget:getItemId() - end - pushWindow.runeId:setItemId(storage[pushPanelName].pushMaxRuneId) - pushWindow.mwallId.onItemChange = function(widget) - storage[pushPanelName].mwallBlockId = widget:getItemId() - end - pushWindow.mwallId:setItemId(storage[pushPanelName].mwallBlockId) - - pushWindow.hotkey.onTextChange = function(widget, text) - storage[pushPanelName].pushMaxKey = text - end - pushWindow.hotkey:setText(storage[pushPanelName].pushMaxKey) -end - - -function matchPosition(curX, curY, destX, destY) - return (curX == destX and curY == destY) -end - -local target -local targetTile -local targetOldPos -macro(10, function() - if not storage[pushPanelName].enabled then return end - if target and targetTile then - if not matchPosition(target:getPosition().x, target:getPosition().y, targetTile:getPosition().x, targetTile:getPosition().y) then - local tile = g_map.getTile(target:getPosition()) - targetOldPos = tile:getPosition() - if tile then - if tile:getTopUseThing():isPickupable() or not tile:getTopUseThing():isNotMoveable() then - useWith(tonumber(storage[pushPanelName].pushMaxRuneId), target) - delay(10) - end - if targetTile:getTopThing():getId() == 2129 or targetTile:getTopThing():getId() == 2130 or targetTile:getTopThing():getId() == tonumber(storage[pushPanelName].mwallBlockId) then - if targetTile:getTimer() <= tonumber(storage[pushPanelName].pushDelay) then - info("now") - g_game.move(target, targetTile:getPosition()) - tile:setText("") - targetTile:setText("") - target = nil - targetTile = nil - end - else - g_game.move(target, targetTile:getPosition()) - delay(1250) - end - end - else - if targetOldPos then - local tile = g_map.getTile(targetOldPos) - if tile then - tile:setText("") - targetTile:setText("") - end - end - target = nil - targetTile = nil - end - end -end) - -local resetTimer = now -onKeyDown(function(keys) - if not storage[pushPanelName].enabled then return end - if keys == storage[pushPanelName].pushMaxKey and resetTimer == 0 then - if not target then - local tile = getTileUnderCursor() - if tile and getDistanceBetween(pos(), tile:getPosition()) <= 1 then - if tile:getCreatures()[1] then - target = tile:getCreatures()[1] - tile:setText("PUSH TARGET") - end - end - else - local tile = getTileUnderCursor() - if tile and not tile:getCreatures()[1] then - targetTile = tile - tile:setText("DESTINATION") - end - end - resetTimer = now - end -end) - - -onKeyPress(function(keys) - if not storage[pushPanelName].enabled then return end - if keys == storage.pushMaxKey and (resetTimer - now) < -10 then - for _, tile in ipairs(g_map.getTiles(posz())) do - if getDistanceBetween(pos(), tile:getPosition()) < 3 then - if tile:getText() ~= "" then - tile:setText("") - end - end - end - target = nil - targetTile = nil - resetTimer = 0 - else - resetTimer = 0 - end -end) - -onCreaturePositionChange(function(creature, newPos, oldPos) - if target and storage[pushPanelName].enabled then - if creature:getName() == target:getName() then - target = nil - targetTile = nil - for _, tile in ipairs(g_map.getTiles(posz())) do - if getDistanceBetween(pos(), tile:getPosition()) < 3 then - if tile:getText() ~= "" then - tile:setText("") - end - end - end - end - end -end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/Title.lua b/modules/game_bot/default_configs/vBot/Title.lua deleted file mode 100644 index 506cf97..0000000 --- a/modules/game_bot/default_configs/vBot/Title.lua +++ /dev/null @@ -1,20 +0,0 @@ -local vocation = player:getVocation() -local vocText = "" - -if vocation == 1 or vocation == 11 then - vocText = "- EK" -elseif vocation == 2 or vocation == 12 then - vocText = "- RP" -elseif vocation == 3 or vocation == 13 then - vocText = "- MS" -elseif vocation == 4 or vocation == 14 then - vocText = "- ED" -end - -macro(2000, function() - if hppercent() > 0 then - g_window.setTitle("Tibia - " .. player:getName() .. " - " .. lvl() .. "lvl " .. vocText) - else - g_window.setTitle("Tibia - " .. player:getName() .. " - DEAD") - end -end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/_Conditions.lua b/modules/game_bot/default_configs/vBot/_Conditions.lua deleted file mode 100644 index d4e8b86..0000000 --- a/modules/game_bot/default_configs/vBot/_Conditions.lua +++ /dev/null @@ -1,242 +0,0 @@ -setDefaultTab("HP") - local conditionPanelName = "ConditionPanel" - local ui = setupUI([[ -Panel - height: 19 - - BotSwitch - id: title - anchors.top: parent.top - anchors.left: parent.left - text-align: center - width: 130 - !text: tr('Conditions') - - Button - id: conditionList - anchors.top: prev.top - anchors.left: prev.right - anchors.right: parent.right - margin-left: 3 - height: 17 - text: Setup - - ]]) - ui:setId(conditionPanelName) - - if not storage[conditionPanelName] then - storage[conditionPanelName] = { - enabled = false, - curePosion = false, - poisonCost = 20, - cureCurse = false, - curseCost = 80, - cureBleed = false, - bleedCost = 45, - cureBurn = false, - burnCost = 30, - cureElectrify = false, - electrifyCost = 22, - cureParalyse = false, - paralyseCost = 40, - paralyseSpell = "utani hur", - holdHaste = false, - hasteCost = 40, - hasteSpell = "utani hur", - holdUtamo = false, - utamoCost = 40, - holdUtana = false, - utanaCost = 440, - holdUtura = false, - uturaType = "", - uturaCost = 100, - ignoreInPz = true, - stopHaste = false - } - end - - ui.title:setOn(storage[conditionPanelName].enabled) - ui.title.onClick = function(widget) - storage[conditionPanelName].enabled = not storage[conditionPanelName].enabled - widget:setOn(storage[conditionPanelName].enabled) - end - - ui.conditionList.onClick = function(widget) - conditionsWindow:show() - conditionsWindow:raise() - conditionsWindow:focus() - end - - - - local rootWidget = g_ui.getRootWidget() - if rootWidget then - conditionsWindow = g_ui.createWidget('ConditionsWindow', rootWidget) - conditionsWindow:hide() - - -- text edits - conditionsWindow.Cure.PoisonCost:setText(storage[conditionPanelName].poisonCost) - conditionsWindow.Cure.PoisonCost.onTextChange = function(widget, text) - storage[conditionPanelName].poisonCost = tonumber(text) - end - - conditionsWindow.Cure.CurseCost:setText(storage[conditionPanelName].curseCost) - conditionsWindow.Cure.CurseCost.onTextChange = function(widget, text) - storage[conditionPanelName].curseCost = tonumber(text) - end - - conditionsWindow.Cure.BleedCost:setText(storage[conditionPanelName].bleedCost) - conditionsWindow.Cure.BleedCost.onTextChange = function(widget, text) - storage[conditionPanelName].bleedCost = tonumber(text) - end - - conditionsWindow.Cure.BurnCost:setText(storage[conditionPanelName].burnCost) - conditionsWindow.Cure.BurnCost.onTextChange = function(widget, text) - storage[conditionPanelName].burnCost = tonumber(text) - end - - conditionsWindow.Cure.ElectrifyCost:setText(storage[conditionPanelName].electrifyCost) - conditionsWindow.Cure.ElectrifyCost.onTextChange = function(widget, text) - storage[conditionPanelName].electrifyCost = tonumber(text) - end - - conditionsWindow.Cure.ParalyseCost:setText(storage[conditionPanelName].paralyseCost) - conditionsWindow.Cure.ParalyseCost.onTextChange = function(widget, text) - storage[conditionPanelName].paralyseCost = tonumber(text) - end - - conditionsWindow.Cure.ParalyseSpell:setText(storage[conditionPanelName].paralyseSpell) - conditionsWindow.Cure.ParalyseSpell.onTextChange = function(widget, text) - storage[conditionPanelName].paralyseSpell = text - end - - conditionsWindow.Hold.HasteSpell:setText(storage[conditionPanelName].hasteSpell) - conditionsWindow.Hold.HasteSpell.onTextChange = function(widget, text) - storage[conditionPanelName].hasteSpell = text - end - - conditionsWindow.Hold.HasteCost:setText(storage[conditionPanelName].hasteCost) - conditionsWindow.Hold.HasteCost.onTextChange = function(widget, text) - storage[conditionPanelName].hasteCost = tonumber(text) - end - - conditionsWindow.Hold.UtamoCost:setText(storage[conditionPanelName].utamoCost) - conditionsWindow.Hold.UtamoCost.onTextChange = function(widget, text) - storage[conditionPanelName].utamoCost = tonumber(text) - end - - conditionsWindow.Hold.UtanaCost:setText(storage[conditionPanelName].utanaCost) - conditionsWindow.Hold.UtanaCost.onTextChange = function(widget, text) - storage[conditionPanelName].utanaCost = tonumber(text) - end - - conditionsWindow.Hold.UturaCost:setText(storage[conditionPanelName].uturaCost) - conditionsWindow.Hold.UturaCost.onTextChange = function(widget, text) - storage[conditionPanelName].uturaCost = tonumber(text) - end - - -- combo box - conditionsWindow.Hold.UturaType:setOption(storage[conditionPanelName].uturaType) - conditionsWindow.Hold.UturaType.onOptionChange = function(widget) - storage[conditionPanelName].uturaType = widget:getCurrentOption().text - end - - -- checkboxes - conditionsWindow.Cure.CurePoison:setChecked(storage[conditionPanelName].curePoison) - conditionsWindow.Cure.CurePoison.onClick = function(widget) - storage[conditionPanelName].curePoison = not storage[conditionPanelName].curePoison - widget:setChecked(storage[conditionPanelName].curePoison) - end - - conditionsWindow.Cure.CureCurse:setChecked(storage[conditionPanelName].cureCurse) - conditionsWindow.Cure.CureCurse.onClick = function(widget) - storage[conditionPanelName].cureCurse = not storage[conditionPanelName].cureCurse - widget:setChecked(storage[conditionPanelName].cureCurse) - end - - conditionsWindow.Cure.CureBleed:setChecked(storage[conditionPanelName].cureBleed) - conditionsWindow.Cure.CureBleed.onClick = function(widget) - storage[conditionPanelName].cureBleed = not storage[conditionPanelName].cureBleed - widget:setChecked(storage[conditionPanelName].cureBleed) - end - - conditionsWindow.Cure.CureBurn:setChecked(storage[conditionPanelName].cureBurn) - conditionsWindow.Cure.CureBurn.onClick = function(widget) - storage[conditionPanelName].cureBurn = not storage[conditionPanelName].cureBurn - widget:setChecked(storage[conditionPanelName].cureBurn) - end - - conditionsWindow.Cure.CureElectrify:setChecked(storage[conditionPanelName].cureElectrify) - conditionsWindow.Cure.CureElectrify.onClick = function(widget) - storage[conditionPanelName].cureElectrify = not storage[conditionPanelName].cureElectrify - widget:setChecked(storage[conditionPanelName].cureElectrify) - end - - conditionsWindow.Cure.CureParalyse:setChecked(storage[conditionPanelName].cureParalyse) - conditionsWindow.Cure.CureParalyse.onClick = function(widget) - storage[conditionPanelName].cureParalyse = not storage[conditionPanelName].cureParalyse - widget:setChecked(storage[conditionPanelName].cureParalyse) - end - - conditionsWindow.Hold.HoldHaste:setChecked(storage[conditionPanelName].holdHaste) - conditionsWindow.Hold.HoldHaste.onClick = function(widget) - storage[conditionPanelName].holdHaste = not storage[conditionPanelName].holdHaste - widget:setChecked(storage[conditionPanelName].holdHaste) - end - - conditionsWindow.Hold.HoldUtamo:setChecked(storage[conditionPanelName].holdUtamo) - conditionsWindow.Hold.HoldUtamo.onClick = function(widget) - storage[conditionPanelName].holdUtamo = not storage[conditionPanelName].holdUtamo - widget:setChecked(storage[conditionPanelName].holdUtamo) - end - - conditionsWindow.Hold.HoldUtana:setChecked(storage[conditionPanelName].holdUtana) - conditionsWindow.Hold.HoldUtana.onClick = function(widget) - storage[conditionPanelName].holdUtana = not storage[conditionPanelName].holdUtana - widget:setChecked(storage[conditionPanelName].holdUtana) - end - - conditionsWindow.Hold.HoldUtura:setChecked(storage[conditionPanelName].holdUtura) - conditionsWindow.Hold.HoldUtura.onClick = function(widget) - storage[conditionPanelName].holdUtura = not storage[conditionPanelName].holdUtura - widget:setChecked(storage[conditionPanelName].holdUtura) - end - - conditionsWindow.Hold.IgnoreInPz:setChecked(storage[conditionPanelName].ignoreInPz) - conditionsWindow.Hold.IgnoreInPz.onClick = function(widget) - storage[conditionPanelName].ignoreInPz = not storage[conditionPanelName].ignoreInPz - widget:setChecked(storage[conditionPanelName].ignoreInPz) - end - - conditionsWindow.Hold.StopHaste:setChecked(storage[conditionPanelName].stopHaste) - conditionsWindow.Hold.StopHaste.onClick = function(widget) - storage[conditionPanelName].stopHaste = not storage[conditionPanelName].stopHaste - widget:setChecked(storage[conditionPanelName].stopHaste) - end - - -- buttons - conditionsWindow.closeButton.onClick = function(widget) - conditionsWindow:hide() - end - end - - local utanaCast = nil - macro(500, function() - if not storage[conditionPanelName].enabled or modules.game_cooldown.isGroupCooldownIconActive(2) then return end - if storage[conditionPanelName].curePoison and mana() >= storage[conditionPanelName].poisonCost and isPoisioned() then say("exana pox") - elseif storage[conditionPanelName].cureCurse and mana() >= storage[conditionPanelName].curseCost and isCursed() then say("exana mort") - elseif storage[conditionPanelName].cureBleed and mana() >= storage[conditionPanelName].bleedCost and isBleeding() then say("exana kor") - elseif storage[conditionPanelName].cureBurn and mana() >= storage[conditionPanelName].burnCost and isBurning() then say("exana flam") - elseif storage[conditionPanelName].cureElectrify and mana() >= storage[conditionPanelName].electrifyCost and isEnergized() then say("exana vis") - elseif (not storage[conditionPanelName].ignoreInPz or not isInPz()) and storage[conditionPanelName].holdUtura and mana() >= storage[conditionPanelName].uturaCost and not hasPartyBuff() then say(storage[conditionPanelName].uturaType) - elseif (not storage[conditionPanelName].ignoreInPz or not isInPz()) and storage[conditionPanelName].holdUtana and mana() >= storage[conditionPanelName].utanaCost and (not utanaCast or (now - utanaCast > 120000)) then say("utana vid") utanaCast = now - end - end) - - macro(50, function() - if not storage[conditionPanelName].enabled then return end - if (not storage[conditionPanelName].ignoreInPz or not isInPz()) and storage[conditionPanelName].holdUtamo and mana() >= storage[conditionPanelName].utamoCost and not hasManaShield() then say("utamo vita") - elseif (not storage[conditionPanelName].ignoreInPz or not isInPz()) and storage[conditionPanelName].holdHaste and mana() >= storage[conditionPanelName].hasteCost and not hasHaste() and not getSpellCoolDown(storage[conditionPanelName].hasteSpell) and (not target() or not storage[conditionPanelName].stopHaste or TargetBot.isCaveBotActionAllowed()) then say(storage[conditionPanelName].hasteSpell) - elseif storage[conditionPanelName].cureParalyse and mana() >= storage[conditionPanelName].paralyseCost and isParalyzed() and not getSpellCoolDown(storage[conditionPanelName].paralyseSpell) then say(storage[conditionPanelName].paralyseSpell) - end - end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/__vlib.lua b/modules/game_bot/default_configs/vBot/__vlib.lua deleted file mode 100644 index 6977f91..0000000 --- a/modules/game_bot/default_configs/vBot/__vlib.lua +++ /dev/null @@ -1,889 +0,0 @@ --- Author: Vithrax --- contains mostly basic function shortcuts and code shorteners - - --- burst damage calculation, for function burstDamageValue() -local dmgTable = {} -local lastDmgMessage = now -onTextMessage(function(mode, text) - if not text:lower():find("you lose") or not text:lower():find("due to") then return end - local dmg = string.match(text, "%d+") - if #dmgTable > 0 then - for k, v in ipairs(dmgTable) do - if now - v.t > 3000 then - table.remove(dmgTable, k) - end - end - end - lastDmgMessage = now - table.insert(dmgTable, {d = dmg, t = now}) - schedule(3050, function() - if now - lastDmgMessage > 3000 then - dmgTable = {} end - end) -end) - -function whiteInfoMessage(text) - return modules.game_textmessage.displayGameMessage(text) -end - -function burstDamageValue() - local d = 0 - local time = 0 - if #dmgTable > 1 then - for i, v in ipairs(dmgTable) do - if i == 1 then - time = v.t - end - d = d + v.d - end - end - return math.ceil(d/((now-time)/1000)) -end - - -function scheduleNpcSay(text, delay) - if not text or not delay then return false end - - return schedule(delay, function() NPC.say(text) end) -end - -function getFirstNumberInText(text) - local n = 0 - if string.match(text, "%d+") then - n = tonumber(string.match(text, "%d+")) - end - return n -end - -function isOnTile(id, p1, p2, p3) - if not id then return end - local tile - if type(p1) == "table" then - tile = g_map.getTile(p1) - elseif type(p1) ~= "number" then - tile = p1 - else - local p = getPos(p1, p2, p3) - tile = g_map.getTile(p) - end - if not tile then return end - - local item = false - if #tile:getItems() ~= 0 then - for i,v in ipairs(tile:getItems()) do - if v:getId() == id then - item = true - end - end - else - return false - end - - return item -end - -function getPos(x,y,z) - if not x or not y or not z then return nil end - local pos = pos() - pos.x = x - pos.y = y - pos.z = z - - return pos -end - -function openPurse() - return g_game.use(g_game.getLocalPlayer():getInventoryItem(InventorySlotPurse)) -end - -function containerIsFull(c) - if not c then return false end - - if c:getCapacity() > #c:getItems() then - return false - else - return true - end - -end - -function isBuffed() - local var = false - for i=1,4 do - local premium = (player:getSkillLevel(i) - player:getSkillBaseLevel(i)) - local base = player:getSkillBaseLevel(i) - if hasPartyBuff() and (premium/100)*305 > base then - var = true - end - end - return var -end - -function reindexTable(t) - if not t or type(t) ~= "table" then return end - - local i = 0 - for _, e in pairs(t) do - i = i + 1 - e.index = i - end -end - -function killsToRs() - return math.min(g_game.getUnjustifiedPoints().killsDayRemaining, g_game.getUnjustifiedPoints().killsWeekRemaining, g_game.getUnjustifiedPoints().killsMonthRemaining) -end - --- [[ experimental healing cooldown calculation ]] -- -storage.isUsingPotion = false -onTalk(function(name, level, mode, text, channelId, pos) - if name ~= player:getName() then return end - if mode ~= 34 then return end - - if text == "Aaaah..." then - storage.isUsingPotion = true - schedule(950, function() - storage.isUsingPotion = false - end) - end -end) - --- [[ eof ]] -- - --- [[ canCast and cast functions ]] -- -SpellCastTable = {} -onTalk(function(name, level, mode, text, channelId, pos) - if name ~= player:getName() then return end - - if SpellCastTable[text] then - SpellCastTable[text].t = now - end -end) - -function cast(text, delay) - if type(text) ~= "string" then return end - if not delay or delay < 100 then - return say(text) -- if not added delay or delay is really low then just treat it like casual say - end - if not SpellCastTable[text] or SpellCastTable[text].d ~= delay then - SpellCastTable[text] = {t=now-delay,d=delay} - return say(text) - end - local lastCast = SpellCastTable[text].t - local spellDelay = SpellCastTable[text].d - if now - lastCast > spellDelay then - return say(text) - end - return -end -local Spells = modules.gamelib.SpellInfo['Default'] -function canCast(spell, ignoreRL, ignoreCd) - if type(spell) ~= "string" then return end - spell = spell:lower() - if not getSpellData(spell) then - if SpellCastTable[spell] then - if now - SpellCastTable[spell].t > SpellCastTable[spell].d then - return true - else - return false - end - else - return true - end - end - if (ignoreCd or not getSpellCoolDown(spell)) and (ignoreRL or level() >= getSpellData(spell).level and mana() >= getSpellData(spell).mana) then - return true - else - return false - end -end - -function getSpellData(spell) - if not spell then return false end - spell = spell:lower() - local t = nil - for k,v in pairs(Spells) do - if v.words == spell then - t = k - break - end - end - if t then - return Spells[t] - else - return false - end -end - -function getSpellCoolDown(text) - if not text then return false end - text = text:lower() - if not getSpellData(text) then return false end - for i,v in pairs(Spells) do - if v.words == text then - return modules.game_cooldown.isCooldownIconActive(v.id) - end - end -end - -storage.isUsing = false - -onUse(function(pos, itemId, stackPos, subType) - if pos.x < 65000 then - storage.isUsing = true - end - schedule(1500, function() if storage.isUsing then storage.isUsing = false end end) -end) - -onUseWith(function(pos, itemId, target, subType) - if itemId ~= 3180 then return end - if pos.x < 65000 then - storage.isUsing = true - end - schedule(1500, function() if storage.isUsing then storage.isUsing = false end end) -end) - -function string.starts(String,Start) - return string.sub(String,1,string.len(Start))==Start -end - -local cachedFriends = {} -local cachedNeutrals = {} -local cachedEnemies = {} -function isFriend(c) - local name = c - if type(c) ~= "string" then - if c == player then return true end - name = c:getName() - if name == name() then return true end - end - - if table.find(cachedFriends, c) then return true end - if table.find(cachedNeutrals, c) or table.find(cachedEnemies, c) then return false end - - if table.find(storage.playerList.friendList, name) then - table.insert(cachedFriends, c) - return true - elseif string.find(storage.serverMembers, name) then - table.insert(cachedFriends, c) - return true - elseif storage.playerList.groupMembers then - local p = c - if type(c) == "string" then - p = getCreatureByName(c, true) - end - if p:isLocalPlayer() then return true end - if p:isPlayer() then - if ((p:getShield() >= 3 and p:getShield() <= 10) or p:getEmblem() == 2) then - table.insert(cachedFriends, c) - table.insert(cachedFriends, p) - return true - else - table.insert(cachedNeutrals, c) - table.insert(cachedNeutrals, p) - return false - end - end - else - table.insert(cachedNeutrals, c) - table.insert(cachedNeutrals, p) - return false - end -end - -function isEnemy(name) - if not name then return false end - local p = getCreatureByName(name, true) - if p:isLocalPlayer() then return end - - if p:isPlayer() and table.find(storage.playerList.enemyList, name) or (storage.playerList.marks and not isFriend(name)) then - return true - else - return false - end -end - -function isAttSpell(expr) - if string.starts(expr, "exori") or string.starts(expr, "exevo") then - return true - else - return false - end -end - -function getActiveItemId(id) - if not id then - return false - end - - if id == 3049 then - return 3086 - elseif id == 3050 then - return 3087 - elseif id == 3051 then - return 3088 - elseif id == 3052 then - return 3089 - elseif id == 3053 then - return 3090 - elseif id == 3091 then - return 3094 - elseif id == 3092 then - return 3095 - elseif id == 3093 then - return 3096 - elseif id == 3097 then - return 3099 - elseif id == 3098 then - return 3100 - elseif id == 16114 then - return 16264 - elseif id == 23531 then - return 23532 - elseif id == 23533 then - return 23534 - elseif id == 23529 then - return 23530 - else - return id - end -end - -function getInactiveItemId(id) - if not id then - return false - end - - if id == 3086 then - return 3049 - elseif id == 3087 then - return 3050 - elseif id == 3088 then - return 3051 - elseif id == 3089 then - return 3052 - elseif id == 3090 then - return 3053 - elseif id == 3094 then - return 3091 - elseif id == 3095 then - return 3092 - elseif id == 3096 then - return 3093 - elseif id == 3099 then - return 3097 - elseif id == 3100 then - return 3098 - elseif id == 16264 then - return 16114 - elseif id == 23532 then - return 23531 - elseif id == 23534 then - return 23533 - elseif id == 23530 then - return 23529 - else - return id - end -end - -function getMonstersInRange(pos, range) - if not pos or not range then - return false - end - local monsters = 0 - for i, spec in pairs(getSpectators()) do - if spec:isMonster() and (g_game.getClientVersion() < 960 or spec:getType() < 3) and getDistanceBetween(pos, spec:getPosition()) < range then - monsters = monsters + 1 - end - end - return monsters -end - -function distanceFromPlayer(coords) - if not coords then - return false - end - return getDistanceBetween(pos(), coords) -end - -function getMonsters(range, multifloor) - if not range then - range = 10 - end - local mobs = 0; - for _, spec in pairs(getSpectators(multifloor)) do - mobs = (g_game.getClientVersion() < 960 or spec:getType() < 3) and spec:isMonster() and distanceFromPlayer(spec:getPosition()) <= range and mobs + 1 or mobs; - end - return mobs; -end - -function getPlayers(range, multifloor) - if not range then - range = 10 - end - local specs = 0; - for _, spec in pairs(getSpectators(multifloor)) do - specs = not spec:isLocalPlayer() and spec:isPlayer() and distanceFromPlayer(spec:getPosition()) <= range and not ((spec:getShield() >= 3 and spec:getShield() <= 10) or spec:getEmblem() == 1) and specs + 1 or specs; - end - return specs; -end - -function isBlackListedPlayerInRange(range) - if #storage.playerList.blackList == 0 then return end - if not range then range = 10 end - local safe = false - for _, spec in pairs(getSpectators()) do - if spec:isPlayer() and distanceFromPlayer(spec:getPosition()) < range then - if table.find(storage.playerList.blackList, spec:getName()) then - safe = true - end - end - end - - return safe -end - -function isSafe(range, multifloor, padding) - local onSame = 0 - local onAnother = 0 - if not multifloor and padding then - multifloor = false - padding = false - end - - for _, spec in pairs(getSpectators(multifloor)) do - if spec:isPlayer() and not spec:isLocalPlayer() and not isFriend(spec:getName()) then - if spec:getPosition().z == posz() and distanceFromPlayer(spec:getPosition()) <= range then - onSame = onSame + 1 - end - if multifloor and padding and spec:getPosition().z ~= posz() and distanceFromPlayer(spec:getPosition()) <= (range + padding) then - onAnother = onAnother + 1 - end - end - end - - if onSame + onAnother > 0 then - return false - else - return true - end -end - -function getAllPlayers(range, multifloor) - if not range then - range = 10 - end - local specs = 0; - for _, spec in pairs(getSpectators(multifloor)) do - specs = not spec:isLocalPlayer() and spec:isPlayer() and distanceFromPlayer(spec:getPosition()) <= range and specs + 1 or specs; - end - return specs; -end - -function getNpcs(range, multifloor) - if not range then - range = 10 - end - local npcs = 0; - for _, spec in pairs(getSpectators(multifloor)) do - npcs = spec:isNpc() and distanceFromPlayer(spec:getPosition()) <= range and npcs + 1 or npcs; - end - return npcs; -end - -function itemAmount(id) - local totalItemCount = 0 - for _, container in pairs(getContainers()) do - for _, item in ipairs(container:getItems()) do - totalItemCount = item:getId() == id and totalItemCount + item:getCount() or totalItemCount - end - end - if getHead() and getHead():getId() == id then - totalItemCount = totalItemCount + getHead():getCount() - end - if getNeck() and getNeck():getId() == id then - totalItemCount = totalItemCount + getNeck():getCount() - end - if getBack() and getBack():getId() == id then - totalItemCount = totalItemCount + getBack():getCount() - end - if getBody() and getBody():getId() == id then - totalItemCount = totalItemCount + getBody():getCount() - end - if getRight() and getRight():getId() == id then - totalItemCount = totalItemCount + getRight():getCount() - end - if getLeft() and getLeft():getId() == id then - totalItemCount = totalItemCount + getLeft():getCount() - end - if getLeg() and getLeg():getId() == id then - totalItemCount = totalItemCount + getLeg():getCount() - end - if getFeet() and getFeet():getId() == id then - totalItemCount = totalItemCount + getFeet():getCount() - end - if getFinger() and getFinger():getId() == id then - totalItemCount = totalItemCount + getFinger():getCount() - end - if getAmmo() and getAmmo():getId() == id then - totalItemCount = totalItemCount + getAmmo():getCount() - end - return totalItemCount -end - -function hasSupplies() - local items = { - {ID = storage.supplies.item1, minAmount = storage.supplies.item1Min}, - {ID = storage.supplies.item2, minAmount = storage.supplies.item2Min}, - {ID = storage.supplies.item3, minAmount = storage.supplies.item3Min}, - {ID = storage.supplies.item4, minAmount = storage.supplies.item4Min}, - {ID = storage.supplies.item5, minAmount = storage.supplies.item5Min}, - {ID = storage.supplies.item6, minAmount = storage.supplies.item6Min}, - {ID = storage.supplies.item7, minAmount = storage.supplies.item7Min} - } - -- false = no supplies - -- true = supplies available - - local hasSupplies = true - - for i, supply in pairs(items) do - if supply.min and supply.ID then - if supply.ID > 100 and itemAmount(supply.ID) < supply.min then - hasSupplies = false - end - end - end - - return hasSupplies -end - -function cordsToPos(x, y, z) - if not x or not y or not z then - return false - end - local tilePos = pos() - tilePos.x = x - tilePos.y = y - tilePos.z = z - return tilePos -end - -function reachGroundItem(id) - if not id then return nil end - local targetTile - for _, tile in ipairs(g_map.getTiles(posz())) do - if tile:getTopUseThing():getId() == id then - targetTile = tile:getPosition() - end - end - if targetTile then - CaveBot.walkTo(targetTile, 10, {ignoreNonPathable = true, precision=1}) - delay(500*getDistanceBetween(targetTile, pos())) - return true - else - return nil - end -end - -function useGroundItem(id) - if not id then - return nil - end - local targetTile = nil - for _, tile in ipairs(g_map.getTiles(posz())) do - if tile:getTopUseThing():getId() == id then - targetTile = tile:getPosition() - end - end - if targetTile then - g_game.use(g_map.getTile(targetTile):getTopUseThing()) - delay(500*getDistanceBetween(targetTile, pos())) - else - return nil - end -end - -function target() - if not g_game.isAttacking() then - return - else - return g_game.getAttackingCreature() - end -end - -function getTarget() - return target() -end - -function targetPos(dist) - if not g_game.isAttacking() then - return - end - if dist then - return distanceFromPlayer(target():getPosition()) - else - return target():getPosition() - end -end - --- for gunzodus -function reopenPurse() - for i, c in pairs(getContainers()) do - if c:getName():lower() == "loot bag" or c:getName():lower() == "store inbox" then - g_game.close(c) - end - end - schedule(100, function() g_game.use(g_game.getLocalPlayer():getInventoryItem(InventorySlotPurse)) end) - schedule(1400, function() - for i, c in pairs(getContainers()) do - if c:getName():lower() == "store inbox" then - for _, i in pairs(c:getItems()) do - if i:getId() == 23721 then - g_game.open(i, c) - end - end - end - end - end) - return CaveBot.delay(1500) -end - --- getSpectator patterns - -function getCreaturesInArea(param1, param2, param3) - -- param1 - pos/creature - -- param2 - pattern - -- param3 - type of return - -- 1 - everyone, 2 - monsters, 3 - players - local specs = 0 - local monsters = 0 - local players = 0 - for i, spec in pairs(getSpectators(param1, param2)) do - if spec ~= player then - specs = specs + 1 - if spec:isMonster() and (g_game.getClientVersion() < 960 or spec:getType() < 3) then - monsters = monsters + 1 - elseif spec:isPlayer() and not isFriend(spec:getName()) then - players = players +1 - end - end - end - - if param3 == 1 then - return specs - elseif param3 == 2 then - return monsters - else - return players - end -end - -function getBestTileByPatern(pattern, specType, maxDist, safe) - if not pattern or not specType then return end - if not maxDist then maxDist = 4 end - - - local bestTile = nil - local best = nil - -- best area tile to use - for _, tile in pairs(g_map.getTiles(posz())) do - if distanceFromPlayer(tile:getPosition()) <= maxDist then - local minimapColor = g_map.getMinimapColor(tile:getPosition()) - local stairs = (minimapColor >= 210 and minimapColor <= 213) - if tile:canShoot() and tile:isWalkable() and not stairs then - if getCreaturesInArea(tile:getPosition(), pattern, specType) > 0 then - if (not safe or getCreaturesInArea(tile:getPosition(), pattern, 3) == 0) then - local candidate = {pos = tile, count = getCreaturesInArea(tile:getPosition(), pattern, specType)} - if not best or best.count <= candidate.count then - best = candidate - end - end - end - end - end - end - - bestTile = best - - if bestTile then - return bestTile - else - return false - end -end - -function getContainerByName(name) - if type(name) ~= "string" then return nil end - - local d = nil - for i, c in pairs(getContainers()) do - if c:getName():lower() == name:lower() then - d = c - break - end - end - return d -end - -function getContainerByItem(id) - if type(name) ~= "number" then return nil end - - local d = nil - for i, c in pairs(getContainers()) do - if c:getContainerItem():getId() == id then - d = c - break - end - end - return d -end - -LargeUeArea = [[ - 0000001000000 - 0000011100000 - 0000111110000 - 0001111111000 - 0011111111100 - 0111111111110 - 1111111111111 - 0111111111110 - 0011111111100 - 0001111111000 - 0000111110000 - 0000011100000 - 0000001000000 -]] - -NormalUeAreaMs = [[ - 00000100000 - 00011111000 - 00111111100 - 01111111110 - 01111111110 - 11111111111 - 01111111110 - 01111111110 - 00111111100 - 00001110000 - 00000100000 -]] - -NormalUeAreaEd = [[ - 00000100000 - 00001110000 - 00011111000 - 00111111100 - 01111111110 - 11111111111 - 01111111110 - 00111111100 - 00011111000 - 00001110000 - 00000100000 -]] - -smallUeArea = [[ - 0011100 - 0111110 - 1111111 - 1111111 - 1111111 - 0111110 - 0011100 -]] - -largeRuneArea = [[ - 0011100 - 0111110 - 1111111 - 1111111 - 1111111 - 0111110 - 0011100 -]] - -adjacentArea = [[ - 111 - 101 - 111 -]] - -longBeamArea = [[ - 0000000N0000000 - 0000000N0000000 - 0000000N0000000 - 0000000N0000000 - 0000000N0000000 - 0000000N0000000 - 0000000N0000000 - WWWWWWW0EEEEEEE - 0000000S0000000 - 0000000S0000000 - 0000000S0000000 - 0000000S0000000 - 0000000S0000000 - 0000000S0000000 - 0000000S0000000 -]] - -shortBeamArea = [[ - 00000100000 - 00000100000 - 00000100000 - 00000100000 - 00000100000 - EEEEE0WWWWW - 00000S00000 - 00000S00000 - 00000S00000 - 00000S00000 - 00000S00000 -]] - -newWaveArea = [[ - 000NNNNN000 - 000NNNNN000 - 0000NNN0000 - WW00NNN00EE - WWWW0N0EEEE - WWWWW0EEEEE - WWWW0S0EEEE - WW00SSS00EE - 0000SSS0000 - 000SSSSS000 - 000SSSSS000 -]] - -bigWaveArea = [[ - 0000NNN0000 - 0000NNN0000 - 0000NNN0000 - 00000N00000 - WWW00N00EEE - WWWWW0EEEEE - WWW00S00EEE - 00000S00000 - 0000SSS0000 - 0000SSS0000 - 0000SSS0000 -]] - - -smallWaveArea = [[ - 00NNN00 - 00NNN00 - WW0N0EE - WWW0EEE - WW0S0EE - 00SSS00 - 00SSS00 -]] - -diamondArrowArea = [[ - 01110 - 11111 - 11111 - 11111 - 01110 -]] \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/antikick.lua b/modules/game_bot/default_configs/vBot/antikick.lua deleted file mode 100644 index bf9c326..0000000 --- a/modules/game_bot/default_configs/vBot/antikick.lua +++ /dev/null @@ -1,7 +0,0 @@ -local lastMove = now -onPlayerPositionChange(function(newPos, oldPos) - if now - lastMove > 13*60*1000 then - turn(math.random(0,3)) - lastMove = now - end -end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/bless_buy.lua b/modules/game_bot/default_configs/vBot/bless_buy.lua deleted file mode 100644 index de4e68c..0000000 --- a/modules/game_bot/default_configs/vBot/bless_buy.lua +++ /dev/null @@ -1,8 +0,0 @@ -if player:getBlessings() == 0 then - say("!bless") - schedule(2000, function() - if player:getBlessings() == 0 then - warn("!! Blessings not bought !!") - end - end) -end diff --git a/modules/game_bot/default_configs/vBot/cavebot/buy_supplies.lua b/modules/game_bot/default_configs/vBot/cavebot/buy_supplies.lua deleted file mode 100644 index 7b85b7d..0000000 --- a/modules/game_bot/default_configs/vBot/cavebot/buy_supplies.lua +++ /dev/null @@ -1,100 +0,0 @@ -CaveBot.Extensions.BuySupplies = {} - -CaveBot.Extensions.BuySupplies.setup = function() - CaveBot.registerAction("BuySupplies", "#C300FF", function(value, retries) - local item1Count = itemAmount(storage[suppliesPanelName].item1) - local item2Count = itemAmount(storage[suppliesPanelName].item2) - local item3Count = itemAmount(storage[suppliesPanelName].item3) - local item4Count = itemAmount(storage[suppliesPanelName].item4) - local item5Count = itemAmount(storage[suppliesPanelName].item5) - local item6Count = itemAmount(storage[suppliesPanelName].item6) - local item7Count = itemAmount(storage[suppliesPanelName].item7) - local possibleItems = {} - - local val = string.split(value, ",") - local waitVal - if #val == 0 or #val > 2 then - warn("CaveBot[BuySupplies]: incorrect BuySupplies value") - return false - elseif #val == 2 then - waitVal = tonumber(val[2]:trim()) - end - - local npc = getCreatureByName(val[1]:trim()) - if not npc then - print("CaveBot[BuySupplies]: NPC not found") - return false - end - - if not waitVal and #val == 2 then - warn("CaveBot[BuySupplies]: incorrect delay values!") - elseif waitVal and #val == 2 then - delay(waitVal) - end - - if retries > 50 then - print("CaveBot[BuySupplies]: Too many tries, can't buy") - return false - end - - delay(200) - - local pos = player:getPosition() - local npcPos = npc:getPosition() - if math.max(math.abs(pos.x - npcPos.x), math.abs(pos.y - npcPos.y)) > 3 then - CaveBot.walkTo(npcPos, 20, {ignoreNonPathable = true, precision=3}) - delay(300) - return "retry" - end - - local itemList = { - item1 = {ID = storage[suppliesPanelName].item1, maxAmount = storage[suppliesPanelName].item1Max, currentAmount = item1Count}, - item2 = {ID = storage[suppliesPanelName].item2, maxAmount = storage[suppliesPanelName].item2Max, currentAmount = item2Count}, - item3 = {ID = storage[suppliesPanelName].item3, maxAmount = storage[suppliesPanelName].item3Max, currentAmount = item3Count}, - item4 = {ID = storage[suppliesPanelName].item4, maxAmount = storage[suppliesPanelName].item4Max, currentAmount = item4Count}, - item5 = {ID = storage[suppliesPanelName].item5, maxAmount = storage[suppliesPanelName].item5Max, currentAmount = item5Count}, - item6 = {ID = storage[suppliesPanelName].item6, maxAmount = storage[suppliesPanelName].item6Max, currentAmount = item6Count}, - item7 = {ID = storage[suppliesPanelName].item7, maxAmount = storage[suppliesPanelName].item7Max, currentAmount = item7Count} - } - - if not NPC.isTrading() then - NPC.say("hi") - schedule(500, function() NPC.say("trade") end) - return "retry" - end - - -- get items from npc - local npcItems = NPC.getBuyItems() - for i,v in pairs(npcItems) do - table.insert(possibleItems, v.id) - end - - for i, item in pairs(itemList) do - -- info(table.find(possibleItems, item["ID"])) - if item["ID"] and item["ID"] > 100 and table.find(possibleItems, item["ID"]) then - local amountToBuy = item["maxAmount"] - item["currentAmount"] - if amountToBuy > 100 then - for i=1, math.ceil(amountToBuy/100), 1 do - NPC.buy(item["ID"], math.min(100, amountToBuy)) - print("CaveBot[BuySupplies]: bought " .. amountToBuy .. "x " .. item["ID"]) - return "retry" - end - else - if amountToBuy > 0 then - NPC.buy(item["ID"], math.min(100, amountToBuy)) - print("CaveBot[BuySupplies]: bought " .. amountToBuy .. "x " .. item["ID"]) - return "retry" - end - end - end - end - print("CaveBot[BuySupplies]: bought everything, proceeding") - return true - end) - - CaveBot.Editor.registerAction("buysupplies", "buy supplies", { - value="NPC name", - title="Buy Supplies", - description="NPC Name, delay(in ms, optional)", - }) -end \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/cavebot/depositer.lua b/modules/game_bot/default_configs/vBot/cavebot/depositer.lua deleted file mode 100644 index d397c47..0000000 --- a/modules/game_bot/default_configs/vBot/cavebot/depositer.lua +++ /dev/null @@ -1,27 +0,0 @@ -CaveBot.Extensions.Depositer = {} - -local ui - --- first function called, here you should setup your UI -CaveBot.Extensions.Depositer.setup = function() - --ui = UI.createWidget('Label') - --ui:setText("Depositer UI") -end - --- called when cavebot config changes, configData is a table but it can be nil -CaveBot.Extensions.Depositer.onConfigChange = function(configName, isEnabled, configData) - if not configData then return end - -end - --- called when cavebot is saving config, should return table or nil -CaveBot.Extensions.Depositer.onSave = function() - return {} -end - --- bellow add you custom functions --- this function can be used in cavebot function waypoint as: return Depositer.run(retries, prev) --- there are 2 useful parameters - retries (number) and prev (true/false), check actions.lua to learn more -CaveBot.Extensions.Depositer.run = function(retries, prev) - return true -end diff --git a/modules/game_bot/default_configs/vBot/cavebot/follow.lua b/modules/game_bot/default_configs/vBot/cavebot/follow.lua deleted file mode 100644 index c91d984..0000000 --- a/modules/game_bot/default_configs/vBot/cavebot/follow.lua +++ /dev/null @@ -1,47 +0,0 @@ -CaveBot.Extensions.OpenDoors = {} - -CaveBot.Extensions.OpenDoors.setup = function() - CaveBot.registerAction("OpenDoors", "#00FFFF", function(value, retries) - local pos = regexMatch(value, "\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*,\\s*([0-9]+)") - if not pos[1] then - error("CaveBot[OpenDoors]: invalid value. It should be position (x,y,z), is: " .. value) - return false - end - - if retries >= 5 then - print("CaveBot[OpenDoors]: too many tries, can't open doors") - return false -- tried 5 times, can't open - end - - pos = {x=tonumber(pos[1][2]), y=tonumber(pos[1][3]), z=tonumber(pos[1][4])} - - local doorTile - if not doorTile then - for i, tile in ipairs(g_map.getTiles(posz())) do - if tile:getPosition().x == pos.x and tile:getPosition().y == pos.y and tile:getPosition().z == pos.z then - doorTile = tile - end - end - end - - if not doorTile then - return false - end - - if not doorTile:isWalkable() then - use(doorTile:getTopUseThing()) - return "retry" - else - print("CaveBot[OpenDoors]: possible to cross, proceeding") - return true - end - end) - - CaveBot.Editor.registerAction("opendoors", "open doors", { - value=function() return posx() .. "," .. posy() .. "," .. posz() end, - title="Door position", - description="doors position (x,y,z)", - multiline=false, - validation="^\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*,\\s*([0-9]+)$" -}) -end \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/cavebot/supply.lua b/modules/game_bot/default_configs/vBot/cavebot/supply.lua deleted file mode 100644 index 32fbc8b..0000000 --- a/modules/game_bot/default_configs/vBot/cavebot/supply.lua +++ /dev/null @@ -1,31 +0,0 @@ -CaveBot.Extensions.Supply = {} - -local ui - --- first function called, here you should setup your UI -CaveBot.Extensions.Supply.setup = function() - --ui = UI.createWidget('SupplyItemList') - --local widget = UI.createWidget('SupplyItem', ui.list) - --widget.item.onItemChange = function(newItem) - --widget.fields.min.onTextChange = function(newText) - --widget.fields.max.onTextChange = function(newText) - --make it similar to UI.Container, so if there are no free slots, add another one, keep min 4 slots, check if value min/max is number after edit -end - --- called when cavebot config changes, configData is a table but it can be nil -CaveBot.Extensions.Supply.onConfigChange = function(configName, isEnabled, configData) - if not configData then return end - -end - --- called when cavebot is saving config, should return table or nil -CaveBot.Extensions.Supply.onSave = function() - return {} -end - --- bellow add you custom functions --- this function can be used in cavebot function waypoint as: return Supply.run(retries, prev) --- there are 2 useful parameters - retries (number) and prev (true/false), check actions.lua to learn more -CaveBot.Extensions.Supply.run = function(retries, prev) - return true -end diff --git a/modules/game_bot/default_configs/vBot/cavebot/supply.otui b/modules/game_bot/default_configs/vBot/cavebot/supply.otui deleted file mode 100644 index 83c76ac..0000000 --- a/modules/game_bot/default_configs/vBot/cavebot/supply.otui +++ /dev/null @@ -1,72 +0,0 @@ -SupplyItem < Panel - height: 34 - - BotItem - id: item - size: 32 32 - anchors.left: parent.left - anchors.top: parent.top - margin-top: 1 - - Panel - id: fields - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.left: prev.right - anchors.right: parent.right - margin-left: 2 - margin-right: 2 - - Label - id: minLabel - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.horizontalCenter - margin-right: 2 - text-align: center - text: "Min" - - Label - id: maxLabel - anchors.top: parent.top - anchors.left: parent.horizontalCenter - anchors.right: parent.right - margin-left: 2 - text-align: center - text: "Max" - - BotTextEdit - id: min - anchors.top: minLabel.bottom - anchors.left: minLabel.left - anchors.right: minLabel.right - text-align: center - text: 1 - - BotTextEdit - id: max - anchors.top: maxLabel.bottom - anchors.left: maxLabel.left - anchors.right: maxLabel.right - text-align: center - text: 100 - -SupplyItemList < Panel - height: 102 - - ScrollablePanel - id: list - anchors.fill: parent - vertical-scrollbar: scroll - margin-right: 7 - layout: - type: verticalBox - cell-height: 34 - - BotSmallScrollBar - id: scroll - anchors.top: prev.top - anchors.bottom: prev.bottom - anchors.right: parent.right - step: 10 - pixels-scroll: true diff --git a/modules/game_bot/default_configs/vBot/cavebot/supply_check.lua b/modules/game_bot/default_configs/vBot/cavebot/supply_check.lua deleted file mode 100644 index a504e64..0000000 --- a/modules/game_bot/default_configs/vBot/cavebot/supply_check.lua +++ /dev/null @@ -1,70 +0,0 @@ -CaveBot.Extensions.SupplyCheck = {} - -storage.supplyRetries = 0 -CaveBot.Extensions.SupplyCheck.setup = function() - CaveBot.registerAction("supplyCheck", "#db5a5a", function(value) - local softCount = itemAmount(6529) + itemAmount(3549) - local totalItem1 = itemAmount(storage[suppliesPanelName].item1) - local totalItem2 = itemAmount(storage[suppliesPanelName].item2) - local totalItem3 = itemAmount(storage[suppliesPanelName].item3) - local totalItem4 = itemAmount(storage[suppliesPanelName].item4) - local totalItem5 = itemAmount(storage[suppliesPanelName].item5) - local totalItem6 = itemAmount(storage[suppliesPanelName].item6) - - if storage.supplyRetries > 50 then - print("CaveBot[SupplyCheck]: Round limit reached, going back on refill.") - storage.supplyRetries = 0 - return false - elseif (storage[suppliesPanelName].imbues and player:getSkillLevel(11) ~= 100) then - print("CaveBot[SupplyCheck]: Imbues ran out. Going on refill.") - storage.supplyRetries = 0 - return false - elseif (storage[suppliesPanelName].staminaSwitch and stamina() < tonumber(storage[suppliesPanelName].staminaValue)) then - print("CaveBot[SupplyCheck]: Stamina ran out. Going on refill.") - storage.supplyRetries = 0 - return false - elseif (softCount < 1 and storage[suppliesPanelName].SoftBoots) then - print("CaveBot[SupplyCheck]: No soft boots left. Going on refill.") - storage.supplyRetries = 0 - return false - elseif (totalItem1 < tonumber(storage[suppliesPanelName].item1Min) and storage[suppliesPanelName].item1 > 100) then - print("CaveBot[SupplyCheck]: Not enough item: " .. storage[suppliesPanelName].item1 .. "(only " .. totalItem1 .. " left). Going on refill.") - storage.supplyRetries = 0 - return false - elseif (totalItem2 < tonumber(storage[suppliesPanelName].item2Min) and storage[suppliesPanelName].item2 > 100) then - print("CaveBot[SupplyCheck]: Not enough item: " .. storage[suppliesPanelName].item2 .. "(only " .. totalItem2 .. " left). Going on refill.") - storage.supplyRetries = 0 - return false - elseif (totalItem3 < tonumber(storage[suppliesPanelName].item3Min) and storage[suppliesPanelName].item3 > 100) then - print("CaveBot[SupplyCheck]: Not enough item: " .. storage[suppliesPanelName].item3 .. "(only " .. totalItem3 .. " left). Going on refill.") - storage.supplyRetries = 0 - return false - elseif (totalItem4 < tonumber(storage[suppliesPanelName].item4Min) and storage[suppliesPanelName].item4 > 100) then - print("CaveBot[SupplyCheck]: Not enough item: " .. storage[suppliesPanelName].item4 .. "(only " .. totalItem4 .. " left). Going on refill.") - storage.supplyRetries = 0 - return false - elseif (totalItem5 < tonumber(storage[suppliesPanelName].item5Min) and storage[suppliesPanelName].item5 > 100) then - print("CaveBot[SupplyCheck]: Not enough item: " .. storage[suppliesPanelName].item5 .. "(only " .. totalItem5 .. " left). Going on refill.") - storage.supplyRetries = 0 - return false - elseif (totalItem6 < tonumber(storage[suppliesPanelName].item6Min) and storage[suppliesPanelName].item6 > 100) then - print("CaveBot[SupplyCheck]: Not enough item: " .. storage[suppliesPanelName].item6 .. "(only " .. totalItem6 .. " left). Going on refill.") - storage.supplyRetries = 0 - return false - elseif (freecap() < tonumber(storage[suppliesPanelName].capValue) and storage[suppliesPanelName].capSwitch) then - print("CaveBot[SupplyCheck]: Not enough capacity. Going on refill.") - storage.supplyRetries = 0 - return false - else - print("CaveBot[SupplyCheck]: Enough supplies. Hunting. Round (" .. storage.supplyRetries .. "/50)") - storage.supplyRetries = storage.supplyRetries + 1 - return CaveBot.gotoLabel(value) - end - end) - - CaveBot.Editor.registerAction("supplycheck", "supply check", { - value="startHunt", - title="Supply check label", - description="Insert here hunting start label", - }) -end \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/cavebot/travel.lua b/modules/game_bot/default_configs/vBot/cavebot/travel.lua deleted file mode 100644 index 7734dfc..0000000 --- a/modules/game_bot/default_configs/vBot/cavebot/travel.lua +++ /dev/null @@ -1,52 +0,0 @@ -CaveBot.Extensions.Travel = {} - -CaveBot.Extensions.Travel.setup = function() - CaveBot.registerAction("Travel", "#db5a5a", function(value, retries) - local data = string.split(value, ",") - local waitVal = 0 - if #data < 2 or #data > 3 then - warn("CaveBot[Travel]: incorrect travel value!") - return false - elseif #data == 3 then - waitVal = tonumber(data[3]:trim()) - end - - if not waitVal then - warn("CaveBot[Travel]: incorrect travel delay value!") - return false - end - - if retries > 5 then - print("CaveBot[Travel]: too many tries, can't travel") - return false - end - - local npc = getCreatureByName(data[1]:trim()) - if not npc then - print("CaveBot[Travel]: NPC not found, can't travel") - return false - end - - local pos = player:getPosition() - local npcPos = npc:getPosition() - if math.max(math.abs(pos.x - npcPos.x), math.abs(pos.y - npcPos.y)) > 3 then - CaveBot.walkTo(npcPos, 20, {ignoreNonPathable = true, precision=3}) - delay(300) - return "retry" - end - - NPC.say("hi") - schedule(waitVal, function() NPC.say(data[2]:trim()) end) - schedule(2*waitVal, function() NPC.say("yes") end) - delay(3*waitVal) - print("CaveBot[Travel]: travel action finished") - return true - - end) - - CaveBot.Editor.registerAction("travel", "travel", { - value="NPC name, city", - title="Travel", - description="NPC name, City name, delay in ms(optional)", - }) -end \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/kill_counter.lua b/modules/game_bot/default_configs/vBot/kill_counter.lua deleted file mode 100644 index e07bd82..0000000 --- a/modules/game_bot/default_configs/vBot/kill_counter.lua +++ /dev/null @@ -1,22 +0,0 @@ -if type(storage.killedCreatures) ~= "table" then - storage.killedCreatures = {} -end -local regex = "Loot of ([a-z])* ([a-z A-Z]*):" -local regex2 = "Loot of ([a-z A-Z]*):" - -onTextMessage(function(mode, text) - if not text:lower():find("loot of") then return end - local monster - - if #regexMatch(text, regex) == 1 and #regexMatch(text, regex)[1] == 3 then - monster = regexMatch(text, regex)[1][3] - else - monster = regexMatch(text, regex2)[1][2] - end - - if storage.killedCreatures[monster] then - storage.killedCreatures[monster] = storage.killedCreatures[monster] + 1 - else - storage.killedCreatures[monster] = 1 - end -end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/mwall_timer.lua b/modules/game_bot/default_configs/vBot/mwall_timer.lua deleted file mode 100644 index 6dc1ec4..0000000 --- a/modules/game_bot/default_configs/vBot/mwall_timer.lua +++ /dev/null @@ -1,41 +0,0 @@ --- Magic wall & Wild growth timer - --- config -local magicWallId = 2129 -local magicWallTime = 20000 -local wildGrowthId = 2130 -local wildGrowthTime = 45000 - --- script -local activeTimers = {} - -onAddThing(function(tile, thing) - if not thing:isItem() then - return - end - local timer = 0 - if thing:getId() == magicWallId then - timer = magicWallTime - elseif thing:getId() == wildGrowthId then - timer = wildGrowthTime - else - return - end - - local pos = tile:getPosition().x .. "," .. tile:getPosition().y .. "," .. tile:getPosition().z - if not activeTimers[pos] or activeTimers[pos] < now then - activeTimers[pos] = now + timer - end - tile:setTimer(activeTimers[pos] - now) -end) - -onRemoveThing(function(tile, thing) - if not thing:isItem() then - return - end - if (thing:getId() == magicWallId or thing:getId() == wildGrowthId) and tile:getGround() then - local pos = tile:getPosition().x .. "," .. tile:getPosition().y .. "," .. tile:getPosition().z - activeTimers[pos] = nil - tile:setTimer(0) - end -end) diff --git a/modules/game_bot/default_configs/vBot/oberon.lua b/modules/game_bot/default_configs/vBot/oberon.lua deleted file mode 100644 index c28e9da..0000000 --- a/modules/game_bot/default_configs/vBot/oberon.lua +++ /dev/null @@ -1,23 +0,0 @@ -onTalk(function(name, level, mode, text, channelId, pos) - if mode == 34 then - if string.find(text, "world will suffer for") then - say("Are you ever going to fight or do you prefer talking!") - elseif string.find(text, "feet when they see me") then - say("Even before they smell your breath?") - elseif string.find(text, "from this plane") then - say("Too bad you barely exist at all!") - elseif string.find(text, "ESDO LO") then - say("SEHWO ASIMO, TOLIDO ESD") - elseif string.find(text, "will soon rule this world") then - say("Excuse me but I still do not get the message!") - elseif string.find(text, "honourable and formidable") then - say("Then why are we fighting alone right now?") - elseif string.find(text, "appear like a worm") then - say("How appropriate, you look like something worms already got the better of!") - elseif string.find(text, "will be the end of mortal") then - say("Then let me show you the concept of mortality before it!") - elseif string.find(text, "virtues of chivalry") then - say("Dare strike up a Minnesang and you will receive your last accolade!") - end - end -end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/test.lua b/modules/game_bot/default_configs/vBot/test.lua deleted file mode 100644 index 91d8d0e..0000000 --- a/modules/game_bot/default_configs/vBot/test.lua +++ /dev/null @@ -1,9 +0,0 @@ -local m = macro(1000, "Floor Change Delay", function() end) - -onPlayerPositionChange(function(x,y) - if m.isOff() then return end - if CaveBot.isOff() then return end - if x.z ~= y.z then - TargetBot.delay(500) - end -end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/use_all.lua b/modules/game_bot/default_configs/vBot/use_all.lua deleted file mode 100644 index 3491198..0000000 --- a/modules/game_bot/default_configs/vBot/use_all.lua +++ /dev/null @@ -1,40 +0,0 @@ --- config -storage.shovel = 9596 -storage.rope = 9596 -storage.machete = 9596 -storage.scythe = 9596 - -local useId = {34847, 1764, 21051, 30823, 6264, 5282, 20453, 20454, 20474, 11708, 11705, 6257, 6256, 2772, 27260, 2773, 1632, 1633, 1948, 435, 6252, 6253, 5007, 4911, 1629, 1630, 5108, 5107, 5281, 1968, 435, 1948, 5542, 31116, 31120, 30742, 31115, 31118, 20474, 5737, 5736, 5734, 5733, 31202, 31228, 31199, 31200, 33262, 30824, 5125, 5126, 5116, 5117, 8257, 8258, 8255, 8256} -local shovelId = {606, 593, 867} -local ropeId = {17238, 12202, 12935, 386, 421, 21966, 14238} -local macheteId = {2130, 3696} -local scytheId = {3653} - -setDefaultTab("Tools") --- script -hotkey("space", "Use All", function() - if not modules.game_walking.wsadWalking then return end - for _, tile in pairs(g_map.getTiles(posz())) do - if distanceFromPlayer(tile:getPosition()) < 2 then - for _, item in pairs(tile:getItems()) do - -- use - if table.find(useId, item:getId()) then - use(item) - return - elseif table.find(shovelId, item:getId()) then - useWith(storage.shovel, item) - return - elseif table.find(ropeId, item:getId()) then - useWith(storage.rope, item) - return - elseif table.find(macheteId, item:getId()) then - useWith(storage.machete, item) - return - elseif table.find(scytheId, item:getId()) then - useWith(storage.scythe, item) - return - end - end - end - end -end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/z_click_reuse.lua b/modules/game_bot/default_configs/vBot/z_click_reuse.lua deleted file mode 100644 index 680ca7b..0000000 --- a/modules/game_bot/default_configs/vBot/z_click_reuse.lua +++ /dev/null @@ -1,15 +0,0 @@ -setDefaultTab("Tools") - -local reUseToggle = macro(1000, "Click ReUse", "`", function() end) -local excluded = {268, 237, 238, 23373, 266, 236, 239, 7643, 23375, 7642, 23374, 5908, 5942, storage.shovel, storage.rope, storage.machete} - -onUseWith(function(pos, itemId, target, subType) - if reUseToggle.isOn() and not table.find(excluded, itemId) then - schedule(50, function() - item = findItem(itemId) - if item then - modules.game_interface.startUseWith(item) - end - end) - end -end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/z_hold_mwall.lua b/modules/game_bot/default_configs/vBot/z_hold_mwall.lua deleted file mode 100644 index 43c5c67..0000000 --- a/modules/game_bot/default_configs/vBot/z_hold_mwall.lua +++ /dev/null @@ -1,48 +0,0 @@ -setDefaultTab("Tools") -local hotkey = "PageUp" - -local candidates = {} - -local m = macro(20, "Hold Mwall", function() - if #candidates == 0 then return end - - for _, tile in pairs(candidates) do - if tile:canShoot() then - useWith(3180, tile:getTopUseThing()) - end - end -end) - -onRemoveThing(function(tile, thing) - if m.isOff() then return end - if thing:getId() ~= 2129 then return end - if tile:getText():len() > 0 then - table.insert(candidates, tile) - useWith(3180, tile:getTopUseThing()) - end -end) - -onAddThing(function(tile, thing) - if m.isOff() then return end - if thing:getId() ~= 2129 then return end - if tile:getText():len() > 0 then - table.remove(candidates, table.find(candidates,tile)) - end -end) - -onKeyPress(function(keys) - if m.isOff() then return end - if keys ~= hotkey then return end - - local tile = getTileUnderCursor() - if not tile then return end - - if tile:getText():len() > 0 then - tile:setText("") - else - tile:setText("MARKED") - table.insert(candidates, tile) - end -end) - - diff --git a/modules/game_bot/default_configs/vBot/z_mwalls.lua b/modules/game_bot/default_configs/vBot/z_mwalls.lua deleted file mode 100644 index b86310e..0000000 --- a/modules/game_bot/default_configs/vBot/z_mwalls.lua +++ /dev/null @@ -1,27 +0,0 @@ -setDefaultTab("Tools") -local toggle = macro(1000, "mwall step", "F12",function() end) - -onPlayerPositionChange(function(newPos, oldPos) - if oldPos.z ~= posz() then return end - if oldPos then - local tile = g_map.getTile(oldPos) - if toggle.isOn() and tile:isWalkable() then - useWith(3180, tile:getTopUseThing()) - toggle.setOff() - end - end -end) - -local toggle2 = macro(1000, "mwall on target", "F11",function() end) - -onCreaturePositionChange(function(creature, newPos, oldPos) - if creature == target() or creature == g_game.getFollowingCreature() then - if oldPos and oldPos.z == posz() then - local tile2 = g_map.getTile(oldPos) - if toggle2.isOn() and tile2:isWalkable() then - useWith(3180, tile2:getTopUseThing()) - toggle2.setOff() - end - end - end -end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/z_npc_talk.lua b/modules/game_bot/default_configs/vBot/z_npc_talk.lua deleted file mode 100644 index c07f112..0000000 --- a/modules/game_bot/default_configs/vBot/z_npc_talk.lua +++ /dev/null @@ -1,10 +0,0 @@ -macro(50, function() - if not g_game.isAttacking() then return end - - if target() and target():isNpc() then - NPC.say("hi") - NPC.say("trade") - end - delay(950) - -end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/z_open_doors.lua b/modules/game_bot/default_configs/vBot/z_open_doors.lua deleted file mode 100644 index ea01675..0000000 --- a/modules/game_bot/default_configs/vBot/z_open_doors.lua +++ /dev/null @@ -1,46 +0,0 @@ --- [[ script made by Ruu ]] -- --- [[ http://otclient.net/showthread.php?tid=358 ]] -- --- [[ small mod, added many doors id's and diagonal walking and switch ]] -- - -local wsadWalking = modules.game_walking.wsadWalking -local doorsIds = { 5007, 8265, 1629, 1632, 5129, 6252, 6249, 7715, 7712, 7714, 7719, 6256, 1669, 1672, 5125, 5115, 5124, 17701, 17710, 1642, 6260, 5107, 4912, 6251, 5291, 1683, 1696, 1692, 5006, 2179, 5116, 11705, 30772, 30774 } - -setDefaultTab("Tools") -local m = macro(1000, "Auto open doors", function() end) - -function checkForDoors(pos) - local tile = g_map.getTile(pos) - if tile then - local useThing = tile:getTopUseThing() - if useThing and table.find(doorsIds, useThing:getId()) then - g_game.use(useThing) - end - end -end - -onKeyPress(function(keys) - if m.isOff() then return end - local pos = player:getPosition() - if keys == 'Up' or (wsadWalking and keys == 'W') then - pos.y = pos.y - 1 - elseif keys == 'Down' or (wsadWalking and keys == 'S') then - pos.y = pos.y + 1 - elseif keys == 'Left' or (wsadWalking and keys == 'A') then - pos.x = pos.x - 1 - elseif keys == 'Right' or (wsadWalking and keys == 'D') then - pos.x = pos.x + 1 - elseif wsadWalking and keys == "Q" then - pos.y = pos.y - 1 - pos.x = pos.x - 1 - elseif wsadWalking and keys == "E" then - pos.y = pos.y - 1 - pos.x = pos.x + 1 - elseif wsadWalking and keys == "Z" then - pos.y = pos.y + 1 - pos.x = pos.x - 1 - elseif wsadWalking and keys == "C" then - pos.y = pos.y + 1 - pos.x = pos.x + 1 - end - checkForDoors(pos) -end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/z_stake_knife.lua b/modules/game_bot/default_configs/vBot/z_stake_knife.lua deleted file mode 100644 index 217d383..0000000 --- a/modules/game_bot/default_configs/vBot/z_stake_knife.lua +++ /dev/null @@ -1,31 +0,0 @@ -setDefaultTab("Cave") - -UI.Separator() -local knifeBodies = {4272, 4173, 4011, 4025, 4047, 4052, 4057, 4062, 4112, 4212, 4321, 4324, 4327, 10352, 10356, 10360, 10364} -local stakeBodies = {4097, 4137, 8738, 18958} -local fishingBodies = {9582} - - -macro(500,"Stake Bodies", function() - if not CaveBot.isOn() then return end - for i, tile in ipairs(g_map.getTiles(posz())) do - for u,item in ipairs(tile:getItems()) do - if table.find(knifeBodies, item:getId()) and findItem(5908) then - CaveBot.delay(550) - useWith(5908, item) - return - end - if table.find(stakeBodies, item:getId()) and findItem(5942) then - CaveBot.delay(550) - useWith(5942, item) - return - end - if table.find(fishingBodies, item:getId()) and findItem(3483) then - CaveBot.delay(550) - useWith(3483, item) - return - end - end - end - -end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/z_suppliesControl.lua b/modules/game_bot/default_configs/vBot/z_suppliesControl.lua deleted file mode 100644 index a8c4bd8..0000000 --- a/modules/game_bot/default_configs/vBot/z_suppliesControl.lua +++ /dev/null @@ -1,9 +0,0 @@ -setDefaultTab("Cave") - -macro(500, "TargetBot off if low supply", function() - if TargetBot.isOff() then return end - if CaveBot.isOff() then return end - if not hasSupplies() then - TargetBot.setOff() - end -end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_2.01/_Loader.lua b/modules/game_bot/default_configs/vBot_2.01/_Loader.lua new file mode 100644 index 0000000..2df6ede --- /dev/null +++ b/modules/game_bot/default_configs/vBot_2.01/_Loader.lua @@ -0,0 +1,57 @@ +-- load all otui files, order doesn't matter +local configName = modules.game_bot.contentsPanel.config:getCurrentOption().text + +local configFiles = g_resources.listDirectoryFiles("/bot/" .. configName .."/vBot/", true, false) +for i, file in ipairs(configFiles) do + local ext = file:split(".") + if ext[#ext]:lower() == "ui" or ext[#ext]:lower() == "otui" then + g_ui.importStyle(file) + end +end + +local function loadScript(name) + return dofile("/vBot/" .. name .. ".lua") +end + +-- here you can set manually order of scripts +-- libraries should be loaded first +local luaFiles = { + "main", + "vlib", + "new_cavebot_lib", + "configs", -- do not change this and above + "extras", + "playerlist", + "BotServer", + "alarms", + "Conditions", + "pushmax", + "combo", + "HealBot", + "Sio", + "AttackBot", -- last of major modules + "ingame_editor", + "items_management", + "quiver_manager", + "tools", + "antiRs", + "cavebot", + "depot_withdraw", + "eat_food", + "equip", + "exeta", + "info", + "items", + "jewellery_equipper", + "spy_level", + "supplies" +} + +for i, file in ipairs(luaFiles) do + loadScript(file) +end + +setDefaultTab("Main") +UI.Separator() +UI.Label("Private Scripts:") +UI.Separator() \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/cavebot/actions.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/actions.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/cavebot/actions.lua rename to modules/game_bot/default_configs/vBot_2.01/cavebot/actions.lua diff --git a/modules/game_bot/default_configs/vBot/cavebot/bank.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/bank.lua similarity index 69% rename from modules/game_bot/default_configs/vBot/cavebot/bank.lua rename to modules/game_bot/default_configs/vBot_2.01/cavebot/bank.lua index dda9e64..6511ce5 100644 --- a/modules/game_bot/default_configs/vBot/cavebot/bank.lua +++ b/modules/game_bot/default_configs/vBot_2.01/cavebot/bank.lua @@ -40,26 +40,17 @@ CaveBot.Extensions.Bank.setup = function() return false end - local pos = player:getPosition() - local npcPos = npc:getPosition() - if math.max(math.abs(pos.x - npcPos.x), math.abs(pos.y - npcPos.y)) > 3 then - CaveBot.walkTo(npcPos, 20, {ignoreNonPathable = true, precision=3}) - delay(300) + if not CaveBot.ReachNPC(npcName) then return "retry" end if actionType == "deposit" then - NPC.say("hi") - schedule(waitVal, function() NPC.say("deposit all") end) - schedule(waitVal*2, function() NPC.say("yes") end) - CaveBot.delay(waitVal*3) + CaveBot.Conversation("hi", "deposit all", "yes") + CaveBot.delay(storage.extras.talkDelay*3) return true else - NPC.say("hi") - schedule(waitVal, function() NPC.say("withdraw") end) - schedule(waitVal*2, function() NPC.say(value) end) - schedule(waitVal*3, function() NPC.say("yes") end) - CaveBot.delay(waitVal*4) + CaveBot.Conversation("hi", "withdraw", value, "yes") + CaveBot.delay(storage.extras.talkDelay*4) return true end end) diff --git a/modules/game_bot/default_configs/vBot_2.01/cavebot/buy_supplies.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/buy_supplies.lua new file mode 100644 index 0000000..6e957f3 --- /dev/null +++ b/modules/game_bot/default_configs/vBot_2.01/cavebot/buy_supplies.lua @@ -0,0 +1,87 @@ +CaveBot.Extensions.BuySupplies = {} + +CaveBot.Extensions.BuySupplies.setup = function() + CaveBot.registerAction("BuySupplies", "#C300FF", function(value, retries) + local supplies = SuppliesConfig[suppliesPanelName] + local item1Count = itemAmount(supplies.item1) + local item2Count = itemAmount(supplies.item2) + local item3Count = itemAmount(supplies.item3) + local item4Count = itemAmount(supplies.item4) + local item5Count = itemAmount(supplies.item5) + local item6Count = itemAmount(supplies.item6) + local item7Count = itemAmount(supplies.item7) + local possibleItems = {} + + local val = string.split(value, ",") + local waitVal + if #val == 0 or #val > 2 then + warn("CaveBot[BuySupplies]: incorrect BuySupplies value") + return false + elseif #val == 2 then + waitVal = tonumber(val[2]:trim()) + end + + local npcName = val[1]:trim() + local npc = getCreatureByName(npcName) + if not npc then + print("CaveBot[BuySupplies]: NPC not found") + return false + end + + if not waitVal and #val == 2 then + warn("CaveBot[BuySupplies]: incorrect delay values!") + elseif waitVal and #val == 2 then + delay(waitVal) + end + + if retries > 50 then + print("CaveBot[BuySupplies]: Too many tries, can't buy") + return false + end + + if not CaveBot.ReachNPC(npcName) then + return "retry" + end + + local itemList = { + item1 = {ID = supplies.item1, maxAmount = supplies.item1Max, currentAmount = item1Count}, + item2 = {ID = supplies.item2, maxAmount = supplies.item2Max, currentAmount = item2Count}, + item3 = {ID = supplies.item3, maxAmount = supplies.item3Max, currentAmount = item3Count}, + item4 = {ID = supplies.item4, maxAmount = supplies.item4Max, currentAmount = item4Count}, + item5 = {ID = supplies.item5, maxAmount = supplies.item5Max, currentAmount = item5Count}, + item6 = {ID = supplies.item6, maxAmount = supplies.item6Max, currentAmount = item6Count}, + item7 = {ID = supplies.item7, maxAmount = supplies.item7Max, currentAmount = item7Count} + } + + if not NPC.isTrading() then + CaveBot.OpenNpcTrade() + CaveBot.delay(storage.extras.talkDelay*2) + return "retry" + end + + -- get items from npc + local npcItems = NPC.getBuyItems() + for i,v in pairs(npcItems) do + table.insert(possibleItems, v.id) + end + + for i, item in pairs(itemList) do + if item["ID"] and item["ID"] > 100 and table.find(possibleItems, item["ID"]) then + local amountToBuy = item["maxAmount"] - item["currentAmount"] + if amountToBuy > 0 then + NPC.buy(item["ID"], math.min(100, amountToBuy)) + print("CaveBot[BuySupplies]: bought " .. math.min(100, amountToBuy) .. "x " .. item["ID"]) + return "retry" + end + end + end + print("CaveBot[BuySupplies]: bought everything, proceeding") + return true + end) + + CaveBot.Editor.registerAction("buysupplies", "buy supplies", { + value="NPC name", + title="Buy Supplies", + description="NPC Name, delay(in ms, optional)", + }) +end \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/cavebot/cavebot.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/cavebot.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/cavebot/cavebot.lua rename to modules/game_bot/default_configs/vBot_2.01/cavebot/cavebot.lua diff --git a/modules/game_bot/default_configs/vBot/cavebot/cavebot.otui b/modules/game_bot/default_configs/vBot_2.01/cavebot/cavebot.otui similarity index 100% rename from modules/game_bot/default_configs/vBot/cavebot/cavebot.otui rename to modules/game_bot/default_configs/vBot_2.01/cavebot/cavebot.otui diff --git a/modules/game_bot/default_configs/vBot/cavebot/clear_tile.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/clear_tile.lua similarity index 66% rename from modules/game_bot/default_configs/vBot/cavebot/clear_tile.lua rename to modules/game_bot/default_configs/vBot_2.01/cavebot/clear_tile.lua index 2eeb1b3..6bbeba8 100644 --- a/modules/game_bot/default_configs/vBot/cavebot/clear_tile.lua +++ b/modules/game_bot/default_configs/vBot_2.01/cavebot/clear_tile.lua @@ -2,18 +2,26 @@ CaveBot.Extensions.ClearTile = {} CaveBot.Extensions.ClearTile.setup = function() CaveBot.registerAction("ClearTile", "#00FFFF", function(value, retries) - local pos = regexMatch(value, "\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*,\\s*([0-9]+)") - if not pos[1] then + local data = string.split(value, ",") + local pos = {x=tonumber(data[1]), y=tonumber(data[2]), z=tonumber(data[3])} + local doors + if #data == 4 then + doors = true + end + if not #pos == 3 then warn("CaveBot[ClearTile]: invalid value. It should be position (x,y,z), is: " .. value) return false end if retries >= 20 then - print("CaveBot[ClearTile]: too many tries, can't open doors") + print("CaveBot[ClearTile]: too many tries, can't clear it") return false -- tried 20 times, can't clear it end - pos = {x=tonumber(pos[1][2]), y=tonumber(pos[1][3]), z=tonumber(pos[1][4])} + if getDistanceBetween(player:getPosition(), pos) == 0 then + print("CaveBot[ClearTile]: tile reached, proceeding") + return true + end local tile = g_map.getTile(pos) if not tile then print("CaveBot[ClearTile]: can't find tile or tile is unreachable, skipping") @@ -21,16 +29,13 @@ CaveBot.Extensions.ClearTile.setup = function() end -- no items on tile and walkability means we are done - if tile:isWalkable() and tile:getTopUseThing():isNotMoveable() and not tile:hasCreature() then + if tile:isWalkable() and tile:getTopUseThing():isNotMoveable() and not tile:hasCreature() and not doors then print("CaveBot[ClearTile]: tile clear, proceeding") return true end - local pPos = player:getPosition() - local tPos = tile:getPosition() - if math.max(math.abs(pPos.x - tPos.x), math.abs(pPos.y - tPos.y)) ~= 1 then - CaveBot.walkTo(tPos, 20, {ignoreNonPathable = true, precision=3}) - delay(300) + if not CaveBot.MatchPosition(tPos, 3) then + CaveBot.GoTo(tPos, 3) return "retry" end @@ -43,7 +48,7 @@ CaveBot.Extensions.ClearTile.setup = function() local c = tile:getCreatures()[1] if c:isMonster() then attack(c) - + return "retry" -- ok here we will find tile to push player, random elseif c:isPlayer() then local candidates = {} @@ -63,19 +68,24 @@ CaveBot.Extensions.ClearTile.setup = function() end end end - if #tile:getItems() > 1 then - local item = tile:getTopUseThing() - print("CaveBot[ClearTile]: moving item... " .. item:getId().. " from tile") - g_game.move(item, pPos, item:getCount()) + for i, item in ipairs(tile:getItems()) do + if not item:isNotMoveable() then + print("CaveBot[ClearTile]: moving item... " .. item:getId().. " from tile") + g_game.move(item, pPos, item:getCount()) + return "retry" + end + end + if doors then + use(tile:getTopUseThing()) return "retry" end + return "retry" end) CaveBot.Editor.registerAction("cleartile", "clear tile", { value=function() return posx() .. "," .. posy() .. "," .. posz() end, title="position of tile to clear", - description="tile position (x,y,z)", - multiline=false, - validation="^\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*,\\s*([0-9]+)$" + description="tile position (x,y,z), optional true if open doors", + multiline=false }) end \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/cavebot/config.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/config.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/cavebot/config.lua rename to modules/game_bot/default_configs/vBot_2.01/cavebot/config.lua diff --git a/modules/game_bot/default_configs/vBot/cavebot/config.otui b/modules/game_bot/default_configs/vBot_2.01/cavebot/config.otui similarity index 100% rename from modules/game_bot/default_configs/vBot/cavebot/config.otui rename to modules/game_bot/default_configs/vBot_2.01/cavebot/config.otui diff --git a/modules/game_bot/default_configs/vBot/cavebot/d_withdraw.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/d_withdraw.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/cavebot/d_withdraw.lua rename to modules/game_bot/default_configs/vBot_2.01/cavebot/d_withdraw.lua diff --git a/modules/game_bot/default_configs/vBot/cavebot/depositor.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/depositor.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/cavebot/depositor.lua rename to modules/game_bot/default_configs/vBot_2.01/cavebot/depositor.lua diff --git a/modules/game_bot/default_configs/vBot/cavebot/doors.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/doors.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/cavebot/doors.lua rename to modules/game_bot/default_configs/vBot_2.01/cavebot/doors.lua diff --git a/modules/game_bot/default_configs/vBot/cavebot/editor.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/editor.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/cavebot/editor.lua rename to modules/game_bot/default_configs/vBot_2.01/cavebot/editor.lua diff --git a/modules/game_bot/default_configs/vBot/cavebot/editor.otui b/modules/game_bot/default_configs/vBot_2.01/cavebot/editor.otui similarity index 100% rename from modules/game_bot/default_configs/vBot/cavebot/editor.otui rename to modules/game_bot/default_configs/vBot_2.01/cavebot/editor.otui diff --git a/modules/game_bot/default_configs/vBot/cavebot/example_functions.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/example_functions.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/cavebot/example_functions.lua rename to modules/game_bot/default_configs/vBot_2.01/cavebot/example_functions.lua diff --git a/modules/game_bot/default_configs/vBot/cavebot/extension_template.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/extension_template.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/cavebot/extension_template.lua rename to modules/game_bot/default_configs/vBot_2.01/cavebot/extension_template.lua diff --git a/modules/game_bot/default_configs/vBot/cavebot/inbox_withdraw.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/inbox_withdraw.lua similarity index 96% rename from modules/game_bot/default_configs/vBot/cavebot/inbox_withdraw.lua rename to modules/game_bot/default_configs/vBot_2.01/cavebot/inbox_withdraw.lua index 0cd2d9f..80d1251 100644 --- a/modules/game_bot/default_configs/vBot/cavebot/inbox_withdraw.lua +++ b/modules/game_bot/default_configs/vBot_2.01/cavebot/inbox_withdraw.lua @@ -150,7 +150,7 @@ CaveBot.Extensions.InWithdraw.setup = function() local destination for i, container in pairs(getContainers()) do - if container:getCapacity() > #container:getItems() and not string.find(container:getName():lower(), "depot") and not string.find(container:getName():lower(), "loot") and not string.find(container:getName():lower(), "inbox") then + if container:getCapacity() > #container:getItems() and not string.find(container:getName():lower(), "quiver") and not string.find(container:getName():lower(), "depot") and not string.find(container:getName():lower(), "loot") and not string.find(container:getName():lower(), "inbox") then destination = container end end diff --git a/modules/game_bot/default_configs/vBot/cavebot/lure.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/lure.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/cavebot/lure.lua rename to modules/game_bot/default_configs/vBot_2.01/cavebot/lure.lua diff --git a/modules/game_bot/default_configs/vBot/cavebot/pos_check.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/pos_check.lua similarity index 78% rename from modules/game_bot/default_configs/vBot/cavebot/pos_check.lua rename to modules/game_bot/default_configs/vBot_2.01/cavebot/pos_check.lua index acfaee3..bf18844 100644 --- a/modules/game_bot/default_configs/vBot/cavebot/pos_check.lua +++ b/modules/game_bot/default_configs/vBot_2.01/cavebot/pos_check.lua @@ -1,7 +1,6 @@ CaveBot.Extensions.PosCheck = {} - -storage.posCheckRetries = 0 +local posCheckRetries = 0 CaveBot.Extensions.PosCheck.setup = function() CaveBot.registerAction("PosCheck", "#00FFFF", function(value, retries) local tilePos @@ -17,16 +16,16 @@ CaveBot.Extensions.PosCheck.setup = function() tilePos.y = tonumber(data[4]) tilePos.z = tonumber(data[5]) - if storage.posCheckRetries > 10 then - storage.posCheckRetries = 0 + if posCheckRetries > 10 then + posCheckRetries = 0 print("CaveBot[CheckPos]: waypoints locked, too many tries, unclogging cavebot and proceeding") return false elseif (tilePos.z == player:getPosition().z) and (getDistanceBetween(player:getPosition(), tilePos) <= tonumber(data[2])) then - storage.posCheckRetries = 0 + posCheckRetries = 0 print("CaveBot[CheckPos]: position reached, proceeding") return true else - storage.posCheckRetries = storage.posCheckRetries + 1 + posCheckRetries = posCheckRetries + 1 CaveBot.gotoLabel(data[1]) print("CaveBot[CheckPos]: position not-reached, going back to label: " .. data[1]) return false @@ -36,7 +35,7 @@ CaveBot.Extensions.PosCheck.setup = function() end) CaveBot.Editor.registerAction("poscheck", "pos check", { - value=function() return "label" .. "," .. "distance" .. "," .. posx() .. "," .. posy() .. "," .. posz() end, + value=function() return "label" .. "," .. "10" .. "," .. posx() .. "," .. posy() .. "," .. posz() end, title="Location Check", description="label name, accepted dist from coordinates, x, y, z", multiline=false, diff --git a/modules/game_bot/default_configs/vBot/cavebot/recorder.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/recorder.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/cavebot/recorder.lua rename to modules/game_bot/default_configs/vBot_2.01/cavebot/recorder.lua diff --git a/modules/game_bot/default_configs/vBot/cavebot/sell_all.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/sell_all.lua similarity index 69% rename from modules/game_bot/default_configs/vBot/cavebot/sell_all.lua rename to modules/game_bot/default_configs/vBot_2.01/cavebot/sell_all.lua index 1794f0e..08ce208 100644 --- a/modules/game_bot/default_configs/vBot/cavebot/sell_all.lua +++ b/modules/game_bot/default_configs/vBot_2.01/cavebot/sell_all.lua @@ -1,6 +1,6 @@ CaveBot.Extensions.SellAll = {} -storage.sellAllCap = 0 +local sellAllCap = 0 CaveBot.Extensions.SellAll.setup = function() CaveBot.registerAction("SellAll", "#C300FF", function(value, retries) local val = string.split(value, ",") @@ -16,7 +16,8 @@ CaveBot.Extensions.SellAll.setup = function() wait = false end - local npc = getCreatureByName(val[1]) + local npcName = val[1] + local npc = getCreatureByName(npcName) if not npc then print("CaveBot[SellAll]: NPC not found! skipping") return false @@ -27,27 +28,22 @@ CaveBot.Extensions.SellAll.setup = function() return false end - if freecap() == storage.sellAllCap then - storage.sellAllCap = 0 + if freecap() == sellAllCap then + sellAllCap = 0 print("CaveBot[SellAll]: Sold everything, proceeding") return true end delay(800) - - local pos = player:getPosition() - local npcPos = npc:getPosition() - if math.max(math.abs(pos.x - npcPos.x), math.abs(pos.y - npcPos.y)) > 3 then - CaveBot.walkTo(npcPos, 20, {ignoreNonPathable = true, precision=3}) - delay(300) + if not CaveBot.ReachNPC(npcName) then return "retry" end if not NPC.isTrading() then - NPC.say("hi") - schedule(500, function() NPC.say("trade") end) + CaveBot.OpenNpcTrade() + delay(storage.extras.talkDelay*2) else - storage.sellAllCap = freecap() + sellAllCap = freecap() end NPC.sellAll(wait) diff --git a/modules/game_bot/default_configs/vBot_2.01/cavebot/supply_check.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/supply_check.lua new file mode 100644 index 0000000..67af8b8 --- /dev/null +++ b/modules/game_bot/default_configs/vBot_2.01/cavebot/supply_check.lua @@ -0,0 +1,71 @@ +CaveBot.Extensions.SupplyCheck = {} + +SuppliesConfig.supplyRetries = 0 +CaveBot.Extensions.SupplyCheck.setup = function() + CaveBot.registerAction("supplyCheck", "#db5a5a", function(value) + local supplies = SuppliesConfig[suppliesPanelName] + local softCount = itemAmount(6529) + itemAmount(3549) + local totalItem1 = itemAmount(supplies.item1) + local totalItem2 = itemAmount(supplies.item2) + local totalItem3 = itemAmount(supplies.item3) + local totalItem4 = itemAmount(supplies.item4) + local totalItem5 = itemAmount(supplies.item5) + local totalItem6 = itemAmount(supplies.item6) + + if SuppliesConfig.supplyRetries > 50 then + print("CaveBot[SupplyCheck]: Round limit reached, going back on refill.") + SuppliesConfig.supplyRetries = 0 + return false + elseif (supplies.imbues and player:getSkillLevel(11) == 0) then + print("CaveBot[SupplyCheck]: Imbues ran out. Going on refill.") + SuppliesConfig.supplyRetries = 0 + return false + elseif (supplies.staminaSwitch and stamina() < tonumber(supplies.staminaValue)) then + print("CaveBot[SupplyCheck]: Stamina ran out. Going on refill.") + SuppliesConfig.supplyRetries = 0 + return false + elseif (softCount < 1 and supplies.SoftBoots) then + print("CaveBot[SupplyCheck]: No soft boots left. Going on refill.") + SuppliesConfig.supplyRetries = 0 + return false + elseif (totalItem1 < tonumber(supplies.item1Min) and supplies.item1 > 100) then + print("CaveBot[SupplyCheck]: Not enough item: " .. supplies.item1 .. "(only " .. totalItem1 .. " left). Going on refill.") + SuppliesConfig.supplyRetries = 0 + return false + elseif (totalItem2 < tonumber(supplies.item2Min) and supplies.item2 > 100) then + print("CaveBot[SupplyCheck]: Not enough item: " .. supplies.item2 .. "(only " .. totalItem2 .. " left). Going on refill.") + SuppliesConfig.supplyRetries = 0 + return false + elseif (totalItem3 < tonumber(supplies.item3Min) and supplies.item3 > 100) then + print("CaveBot[SupplyCheck]: Not enough item: " .. supplies.item3 .. "(only " .. totalItem3 .. " left). Going on refill.") + SuppliesConfig.supplyRetries = 0 + return false + elseif (totalItem4 < tonumber(supplies.item4Min) and supplies.item4 > 100) then + print("CaveBot[SupplyCheck]: Not enough item: " .. supplies.item4 .. "(only " .. totalItem4 .. " left). Going on refill.") + SuppliesConfig.supplyRetries = 0 + return false + elseif (totalItem5 < tonumber(supplies.item5Min) and supplies.item5 > 100) then + print("CaveBot[SupplyCheck]: Not enough item: " .. supplies.item5 .. "(only " .. totalItem5 .. " left). Going on refill.") + SuppliesConfig.supplyRetries = 0 + return false + elseif (totalItem6 < tonumber(supplies.item6Min) and supplies.item6 > 100) then + print("CaveBot[SupplyCheck]: Not enough item: " .. supplies.item6 .. "(only " .. totalItem6 .. " left). Going on refill.") + SuppliesConfig.supplyRetries = 0 + return false + elseif (freecap() < tonumber(supplies.capValue) and supplies.capSwitch) then + print("CaveBot[SupplyCheck]: Not enough capacity. Going on refill.") + SuppliesConfig.supplyRetries = 0 + return false + else + print("CaveBot[SupplyCheck]: Enough supplies. Hunting. Round (" .. SuppliesConfig.supplyRetries .. "/50)") + SuppliesConfig.supplyRetries = SuppliesConfig.supplyRetries + 1 + return CaveBot.gotoLabel(value) + end + end) + + CaveBot.Editor.registerAction("supplycheck", "supply check", { + value="startHunt", + title="Supply check label", + description="Insert here hunting start label", + }) +end \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/cavebot/tasker.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/tasker.lua similarity index 94% rename from modules/game_bot/default_configs/vBot/cavebot/tasker.lua rename to modules/game_bot/default_configs/vBot_2.01/cavebot/tasker.lua index eaf5166..0b0894a 100644 --- a/modules/game_bot/default_configs/vBot/cavebot/tasker.lua +++ b/modules/game_bot/default_configs/vBot_2.01/cavebot/tasker.lua @@ -6,7 +6,7 @@ local dataValidationFailed = function() end -- miniconfig -local talkDelay = 300 -- default delay between npc messages +local talkDelay = storage.extras.talkDelay if not storage.caveBotTasker then storage.caveBotTasker = { inProgress = false, @@ -80,10 +80,7 @@ CaveBot.Extensions.Tasker.setup = function() -- let's cover markers now if marker == 1 then -- starting task - NPC.say("hi") - scheduleNpcSay("task", talkDelay) - scheduleNpcSay(taskName, talkDelay*2) - scheduleNpcSay("yes", talkDelay*3) + NPC.Conversation("hi", "task", taskName, "yes") delay(talkDelay*4) storage.caveBotTasker.monster = monster @@ -117,9 +114,7 @@ CaveBot.Extensions.Tasker.setup = function() elseif marker == 3 then -- reporting task - NPC.say("hi") - scheduleNpcSay("report", talkDelay) - scheduleNpcSay("task", talkDelay*2) + NPC.Conversation("hi", "report", "task") delay(talkDelay*3) resetTaskData() diff --git a/modules/game_bot/default_configs/vBot_2.01/cavebot/travel.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/travel.lua new file mode 100644 index 0000000..8e9d21e --- /dev/null +++ b/modules/game_bot/default_configs/vBot_2.01/cavebot/travel.lua @@ -0,0 +1,40 @@ +CaveBot.Extensions.Travel = {} + +CaveBot.Extensions.Travel.setup = function() + CaveBot.registerAction("Travel", "#db5a5a", function(value, retries) + local data = string.split(value, ",") + if #data < 2 then + warn("CaveBot[Travel]: incorrect travel value!") + return false + end + + local npcName = data[1]:trim() + local dest = data[2]:trim() + + if retries > 5 then + print("CaveBot[Travel]: too many tries, can't travel") + return false + end + + local npc = getCreatureByName(npcName) + if not npc then + print("CaveBot[Travel]: NPC not found, can't travel") + return false + end + + if not CaveBot.ReachNPC(npcName) then + return "retry" + end + + CaveBot.Travel(dest) + delay(storage.extras.talkDelay*3) + print("CaveBot[Travel]: travel action finished") + return true + end) + + CaveBot.Editor.registerAction("travel", "travel", { + value="NPC name, city", + title="Travel", + description="NPC name, City name, delay in ms(default is 200ms)", + }) +end \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/cavebot/walking.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/walking.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/cavebot/walking.lua rename to modules/game_bot/default_configs/vBot_2.01/cavebot/walking.lua diff --git a/modules/game_bot/default_configs/vBot/cavebot/withdraw.lua b/modules/game_bot/default_configs/vBot_2.01/cavebot/withdraw.lua similarity index 96% rename from modules/game_bot/default_configs/vBot/cavebot/withdraw.lua rename to modules/game_bot/default_configs/vBot_2.01/cavebot/withdraw.lua index 74f7fbc..1c4986e 100644 --- a/modules/game_bot/default_configs/vBot/cavebot/withdraw.lua +++ b/modules/game_bot/default_configs/vBot_2.01/cavebot/withdraw.lua @@ -186,7 +186,7 @@ CaveBot.Extensions.Withdraw.setup = function() local destination for i, container in pairs(getContainers()) do - if container:getCapacity() > #container:getItems() and not string.find(container:getName():lower(), "depot") and not string.find(container:getName():lower(), "loot") and not string.find(container:getName():lower(), "inbox") then + if container:getCapacity() > #container:getItems() and not string.find(container:getName():lower(), "quiver") and not string.find(container:getName():lower(), "depot") and not string.find(container:getName():lower(), "loot") and not string.find(container:getName():lower(), "inbox") then destination = container end end diff --git a/modules/game_bot/default_configs/vBot/targetbot/creature.lua b/modules/game_bot/default_configs/vBot_2.01/targetbot/creature.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/targetbot/creature.lua rename to modules/game_bot/default_configs/vBot_2.01/targetbot/creature.lua diff --git a/modules/game_bot/default_configs/vBot/targetbot/creature_attack.lua b/modules/game_bot/default_configs/vBot_2.01/targetbot/creature_attack.lua similarity index 90% rename from modules/game_bot/default_configs/vBot/targetbot/creature_attack.lua rename to modules/game_bot/default_configs/vBot_2.01/targetbot/creature_attack.lua index 68a2c5d..4abb817 100644 --- a/modules/game_bot/default_configs/vBot/targetbot/creature_attack.lua +++ b/modules/game_bot/default_configs/vBot_2.01/targetbot/creature_attack.lua @@ -1,3 +1,9 @@ +local targetBotLure = false +local targetCount = 0 +local delayValue = 0 +local lureMax = 0 +local delayedLure = false + TargetBot.Creature.attack = function(params, targets, isLooting) -- params {config, creature, danger, priority} if player:isWalking() then lastWalk = now @@ -63,9 +69,6 @@ TargetBot.Creature.attack = function(params, targets, isLooting) -- params {conf end end -if not storage.targetBotTargets then - storage.targetBotTargets = 0 -end TargetBot.Creature.walk = function(creature, config, targets) local cpos = creature:getPosition() local pos = player:getPosition() @@ -81,27 +84,27 @@ TargetBot.Creature.walk = function(creature, config, targets) end -- data for external dynamic lure - if config.lureMin and config.lureMax then + if config.lureMin and config.lureMax and config.dynamicLure then if config.lureMin >= targets then - storage.TargetBotLure = true + targetBotLure = true elseif targets >= config.lureMax then - storage.TargetBotLure = false + targetBotLure = false end end - storage.targetBotTargets = targets - storage.targetBotDynamicLureDelayValue = config.lureDelay + + delayedLure = config.dynamicLureDelay + targetCount = targets + delayValue = config.lureDelay - if not storage.targetBotLureMax then - storage.targetBotLureMax = 0 - end if config.lureMax then - storage.targetBotLureMax = config.lureMax + lureMax = config.lureMax end + -- luring if TargetBot.canLure() and (config.lure or config.lureCavebot or config.dynamicLure) and not (config.chase and creature:getHealthPercent() < 5) and not isTrapped then local monsters = 0 - if storage.TargetBotLure then + if targetBotLure then return TargetBot.allowCaveBot(150) else if targets < config.lureCount then @@ -175,8 +178,11 @@ end onPlayerPositionChange(function(newPos, oldPos) if CaveBot.isOff() then return end if TargetBot.isOff() then return end - if not storage.targetBotLureMax then return end - if storage.targetBotTargets < storage.targetBotLureMax/2 or not target() then return end + if not lureMax then return end + if storage.TargetBotDelayWhenPlayer then return end + if not delayedLure then return end - CaveBot.delay(storage.targetBotDynamicLureDelayValue or 0) + + if targetCount < lureMax/2 or not target() then return end + CaveBot.delay(delayValue or 0) end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/targetbot/creature_editor.lua b/modules/game_bot/default_configs/vBot_2.01/targetbot/creature_editor.lua similarity index 98% rename from modules/game_bot/default_configs/vBot/targetbot/creature_editor.lua rename to modules/game_bot/default_configs/vBot_2.01/targetbot/creature_editor.lua index b743f3e..fe9fa9d 100644 --- a/modules/game_bot/default_configs/vBot/targetbot/creature_editor.lua +++ b/modules/game_bot/default_configs/vBot_2.01/targetbot/creature_editor.lua @@ -94,4 +94,5 @@ TargetBot.Creature.edit = function(config, callback) -- callback = function(newC addCheckBox("avoidAttacks", "Avoid wave attacks", false) addCheckBox("dynamicLure", "Dynamic lure", false) addCheckBox("dynamicLureDelay", "Dynamic lure delay", false) + addCheckBox("diamondArrows", "D-Arrows priority", false) end diff --git a/modules/game_bot/default_configs/vBot/targetbot/creature_editor.otui b/modules/game_bot/default_configs/vBot_2.01/targetbot/creature_editor.otui similarity index 99% rename from modules/game_bot/default_configs/vBot/targetbot/creature_editor.otui rename to modules/game_bot/default_configs/vBot_2.01/targetbot/creature_editor.otui index 82ae3ec..9570f87 100644 --- a/modules/game_bot/default_configs/vBot/targetbot/creature_editor.otui +++ b/modules/game_bot/default_configs/vBot_2.01/targetbot/creature_editor.otui @@ -64,7 +64,7 @@ TargetBotCreatureEditorCheckBox < BotSwitch TargetBotCreatureEditorWindow < MainWindow text: TargetBot creature editor width: 500 - height: 400 + height: 425 $mobile: height: 300 diff --git a/modules/game_bot/default_configs/vBot/targetbot/creature_priority.lua b/modules/game_bot/default_configs/vBot_2.01/targetbot/creature_priority.lua similarity index 69% rename from modules/game_bot/default_configs/vBot/targetbot/creature_priority.lua rename to modules/game_bot/default_configs/vBot_2.01/targetbot/creature_priority.lua index dcc2f81..7b4dd47 100644 --- a/modules/game_bot/default_configs/vBot/targetbot/creature_priority.lua +++ b/modules/game_bot/default_configs/vBot_2.01/targetbot/creature_priority.lua @@ -18,9 +18,23 @@ TargetBot.Creature.calculatePriority = function(creature, config, path) -- extra priority for close distance local path_length = #path if path_length == 1 then - priority = priority + 3 + priority = priority + 10 elseif path_length <= 3 then - priority = priority + 1 + priority = priority + 5 + end + + -- extra priority for paladin diamond arrows + if config.diamondArrows then + local mobCount = getCreaturesInArea(creature:getPosition(), diamondArrowArea, 2) + if mobCount > 5 then + priority = priority + 4 + elseif mobCount > 4 then + priority = priority + 3 + elseif mobCount > 3 then + priority = priority + 2 + elseif mobCount > 2 then + priority = priority + 1 + end end -- extra priority for low health diff --git a/modules/game_bot/default_configs/vBot/targetbot/looting.lua b/modules/game_bot/default_configs/vBot_2.01/targetbot/looting.lua similarity index 98% rename from modules/game_bot/default_configs/vBot/targetbot/looting.lua rename to modules/game_bot/default_configs/vBot_2.01/targetbot/looting.lua index 49c090b..df48f06 100644 --- a/modules/game_bot/default_configs/vBot/targetbot/looting.lua +++ b/modules/game_bot/default_configs/vBot_2.01/targetbot/looting.lua @@ -132,7 +132,8 @@ TargetBot.Looting.process = function(targets, dangerLevel) local pos = player:getPosition() local dist = math.max(math.abs(pos.x-loot.pos.x), math.abs(pos.y-loot.pos.y)) - if loot.tries > 30 or loot.pos.z ~= pos.z or dist > 20 then + local maxRange = storage.extras.looting or 40 + if loot.tries > 30 or loot.pos.z ~= pos.z or dist > maxRange then table.remove(TargetBot.Looting.list, 1) return true end diff --git a/modules/game_bot/default_configs/vBot/targetbot/looting.otui b/modules/game_bot/default_configs/vBot_2.01/targetbot/looting.otui similarity index 100% rename from modules/game_bot/default_configs/vBot/targetbot/looting.otui rename to modules/game_bot/default_configs/vBot_2.01/targetbot/looting.otui diff --git a/modules/game_bot/default_configs/vBot/targetbot/target.lua b/modules/game_bot/default_configs/vBot_2.01/targetbot/target.lua similarity index 97% rename from modules/game_bot/default_configs/vBot/targetbot/target.lua rename to modules/game_bot/default_configs/vBot_2.01/targetbot/target.lua index ab29fcb..d71eff3 100644 --- a/modules/game_bot/default_configs/vBot/targetbot/target.lua +++ b/modules/game_bot/default_configs/vBot_2.01/targetbot/target.lua @@ -3,7 +3,8 @@ local config = nil local lastAction = 0 local cavebotAllowance = 0 local lureEnabled = true -storage.targebotDanger = 0 +local dangerValue = 0 +local looterStatus = "" -- ui local configWidget = UI.Config() @@ -69,8 +70,8 @@ targetbotMacro = macro(100, function() -- looting local looting = TargetBot.Looting.process(targets, dangerLevel) local lootingStatus = TargetBot.Looting.getStatus() - storage.lootStatus = TargetBot.Looting.getStatus() - storage.targebotDanger = dangerLevel + looterStatus = TargetBot.Looting.getStatus() + dangerValue = dangerLevel ui.danger.right:setText(dangerLevel) if highestPriorityParams and not isInPz() then @@ -217,11 +218,11 @@ TargetBot.enableLuring = function() end TargetBot.Danger = function() - return storage.dangerLevel or 0 + return dangerValue end TargetBot.lootStatus = function() - return storage.lootStatus or "" + return looterStatus end diff --git a/modules/game_bot/default_configs/vBot/targetbot/target.otui b/modules/game_bot/default_configs/vBot_2.01/targetbot/target.otui similarity index 100% rename from modules/game_bot/default_configs/vBot/targetbot/target.otui rename to modules/game_bot/default_configs/vBot_2.01/targetbot/target.otui diff --git a/modules/game_bot/default_configs/vBot/targetbot/walking.lua b/modules/game_bot/default_configs/vBot_2.01/targetbot/walking.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/targetbot/walking.lua rename to modules/game_bot/default_configs/vBot_2.01/targetbot/walking.lua diff --git a/modules/game_bot/default_configs/vBot/AttackBot.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/AttackBot.lua similarity index 94% rename from modules/game_bot/default_configs/vBot/AttackBot.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/AttackBot.lua index f7a9a64..ea956bd 100644 --- a/modules/game_bot/default_configs/vBot/AttackBot.lua +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/AttackBot.lua @@ -90,8 +90,8 @@ local pvpDedicated = false local item = false -- create blank profiles -if not storage[attackPanelName] or not storage[attackPanelName][1] or #storage[attackPanelName] ~= 5 then - storage[attackPanelName] = { +if not AttackBotConfig[attackPanelName] or not AttackBotConfig[attackPanelName][1] or #AttackBotConfig[attackPanelName] ~= 5 then + AttackBotConfig[attackPanelName] = { [1] = { enabled = false, attackTable = {}, @@ -170,15 +170,15 @@ if not storage[attackPanelName] or not storage[attackPanelName][1] or #storage[a } end -if not storage.currentBotProfile or storage.currentBotProfile == 0 or storage.currentBotProfile > 5 then - storage.currentBotProfile = 1 +if not AttackBotConfig.currentBotProfile or AttackBotConfig.currentBotProfile == 0 or AttackBotConfig.currentBotProfile > 5 then + AttackBotConfig.currentBotProfile = 1 end -- finding correct table, manual unfortunately local currentSettings local setActiveProfile = function() - local n = storage.currentBotProfile - currentSettings = storage[attackPanelName][n] + local n = AttackBotConfig.currentBotProfile + currentSettings = AttackBotConfig[attackPanelName][n] end setActiveProfile() @@ -188,7 +188,7 @@ end local activeProfileColor = function() for i=1,5 do - if i == storage.currentBotProfile then + if i == AttackBotConfig.currentBotProfile then ui[i]:setColor("green") else ui[i]:setColor("white") @@ -252,6 +252,7 @@ local pattern = { ui.title.onClick = function(widget) currentSettings.enabled = not currentSettings.enabled widget:setOn(currentSettings.enabled) +vBotConfigSave("atk") end ui.settings.onClick = function(widget) @@ -262,7 +263,7 @@ end rootWidget = g_ui.getRootWidget() if rootWidget then - attackWindow = g_ui.createWidget('AttackWindow', rootWidget) + attackWindow = UI.createWindow('AttackWindow', rootWidget) attackWindow:hide() -- functions @@ -325,6 +326,7 @@ if rootWidget then --buttons attackWindow.CloseButton.onClick = function(widget) attackWindow:hide() + vBotConfigSave("atk") end local inputTypeToggle = function() @@ -467,7 +469,7 @@ if rootWidget then child:destroy() end for _, entry in pairs(currentSettings.attackTable) do - local label = g_ui.createWidget("AttackEntry", attackWindow.attackList) + local label = UI.createWidget("AttackEntry", attackWindow.attackList) label.enabled:setChecked(entry.enabled) label.enabled.onClick = function(widget) entry.enabled = not entry.enabled @@ -587,7 +589,7 @@ if rootWidget then attackWindow.PvpMode:setChecked(currentSettings.pvpMode) attackWindow.PvpSafe:setChecked(currentSettings.PvpSafe) attackWindow.BlackListSafe:setChecked(currentSettings.BlackListSafe) - attackWindow.AntiRsRange:setValue(currentSettings.AntiRsRnage) + attackWindow.AntiRsRange:setValue(currentSettings.AntiRsRange) end loadSettings() @@ -595,13 +597,14 @@ if rootWidget then setActiveProfile() activeProfileColor() loadSettings() + vBotConfigSave("atk") end -- profile buttons for i=1,5 do local button = ui[i] button.onClick = function() - storage.currentBotProfile = i + AttackBotConfig.currentBotProfile = i profileChange() end end @@ -612,7 +615,7 @@ if rootWidget then currentSettings.ignoreMana = true currentSettings.Kills = false currentSettings.Rotate = false - currentSettings.name = "Profile #" .. storage.currentBotProfile + currentSettings.name = "Profile #" .. AttackBotConfig.currentBotProfile currentSettings.Cooldown = true currentSettings.Visible = true currentSettings.pvpMode = false @@ -647,22 +650,24 @@ if rootWidget then AttackBot.setOff = function() currentSettings.enabled = false ui.title:setOn(currentSettings.enabled) + vBotConfigSave("atk") end AttackBot.setOn = function() currentSettings.enabled = true ui.title:setOn(currentSettings.enabled) + vBotConfigSave("atk") end AttackBot.getActiveProfile = function() - return storage.currentBotProfile -- returns number 1-5 + return AttackBotConfig.currentBotProfile -- returns number 1-5 end AttackBot.setActiveProfile = function(n) if not n or not tonumber(n) or n < 1 or n > 5 then return error("[AttackBot] wrong profile parameter! should be 1 to 5 is " .. n) else - storage.currentBotProfile = n + AttackBotConfig.currentBotProfile = n profileChange() end end @@ -950,7 +955,7 @@ macro(100, function() cast(entry.attack, entry.cd) return else - if not storage.isUsing and target():canShoot() then + if not AttackBotConfig.isUsing and target():canShoot() then g_game.useInventoryItemWith(entry.attack, target()) return end @@ -960,7 +965,7 @@ macro(100, function() if entry.category == 6 or entry.category == 7 then if getMonsters(4) >= entry.minMonsters then if type(entry.attack) == "number" then - if not storage.isUsing then + if not AttackBotConfig.isUsing then g_game.useInventoryItemWith(entry.attack, target()) return end @@ -972,7 +977,7 @@ macro(100, function() else if (g_game.getClientVersion() < 960 or not currentSettings.Kills or killsToRs() > currentSettings.KillsAmount) and (not currentSettings.BlackListSafe or not isBlackListedPlayerInRange(currentSettings.AntiRsRange)) then if entry.category == 8 then - bestTile = getBestTileByPatern(patterns[5], 2, entry.dist, not currentSettings.PvpSafe) + bestTile = getBestTileByPatern(patterns[5], 2, entry.dist, currentSettings.PvpSafe) end if entry.category == 4 and (not currentSettings.PvpSafe or isSafe(2, false)) and bestSide >= entry.minMonsters then cast(entry.attack, entry.cd) @@ -987,7 +992,7 @@ macro(100, function() cast(entry.attack, entry.cd) return elseif entry.category == 8 and bestTile and bestTile.count >= entry.minMonsters then - if not storage.isUsing then + if not AttackBotConfig.isUsing then g_game.useInventoryItemWith(entry.attack, bestTile.pos:getTopUseThing()) end return @@ -998,7 +1003,7 @@ macro(100, function() if entry.category == 6 or entry.category == 7 then if getMonsters(4) >= entry.minMonsters then if type(entry.attack) == "number" then - if not storage.isUsing then + if not AttackBotConfig.isUsing then g_game.useInventoryItemWith(entry.attack, target()) return end @@ -1013,7 +1018,7 @@ macro(100, function() if entry.category == 6 or entry.category == 7 then if getMonsters(4) >= entry.minMonsters then if type(entry.attack) == "number" then - if not storage.isUsing then + if not AttackBotConfig.isUsing then g_game.useInventoryItemWith(entry.attack, target()) return end diff --git a/modules/game_bot/default_configs/vBot/AttackBot.otui b/modules/game_bot/default_configs/vBot_2.01/vBot/AttackBot.otui similarity index 99% rename from modules/game_bot/default_configs/vBot/AttackBot.otui rename to modules/game_bot/default_configs/vBot_2.01/vBot/AttackBot.otui index 5ca5023..a4b7a24 100644 --- a/modules/game_bot/default_configs/vBot/AttackBot.otui +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/AttackBot.otui @@ -27,7 +27,6 @@ AttackEntry < Label AttackWindow < MainWindow !text: tr('AttackBot') size: 800 350 - @onEscape: self:hide() TextList id: attackList diff --git a/modules/game_bot/default_configs/vBot/0_BotSever.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/BotServer.lua similarity index 98% rename from modules/game_bot/default_configs/vBot/0_BotSever.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/BotServer.lua index 55e1604..1fcc56b 100644 --- a/modules/game_bot/default_configs/vBot/0_BotSever.lua +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/BotServer.lua @@ -122,7 +122,6 @@ onAddThing(function(tile, thing) storage[BotPanelName].mwalls[pos] = now + 20000 BotServer.send("mwall", {pos=pos, duration=20000}) end - tile:setTimer(storage[BotPanelName].mwalls[pos] - now) end end end) diff --git a/modules/game_bot/default_configs/vBot/BotServer.otui b/modules/game_bot/default_configs/vBot_2.01/vBot/BotServer.otui similarity index 100% rename from modules/game_bot/default_configs/vBot/BotServer.otui rename to modules/game_bot/default_configs/vBot_2.01/vBot/BotServer.otui diff --git a/modules/game_bot/default_configs/vBot_2.01/vBot/Conditions.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/Conditions.lua new file mode 100644 index 0000000..ed1db4e --- /dev/null +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/Conditions.lua @@ -0,0 +1,247 @@ +setDefaultTab("HP") + local conditionPanelName = "ConditionPanel" + local ui = setupUI([[ +Panel + height: 19 + + BotSwitch + id: title + anchors.top: parent.top + anchors.left: parent.left + text-align: center + width: 130 + !text: tr('Conditions') + + Button + id: conditionList + anchors.top: prev.top + anchors.left: prev.right + anchors.right: parent.right + margin-left: 3 + height: 17 + text: Setup + + ]]) + ui:setId(conditionPanelName) + + if not HealBotConfig[conditionPanelName] then + HealBotConfig[conditionPanelName] = { + enabled = false, + curePosion = false, + poisonCost = 20, + cureCurse = false, + curseCost = 80, + cureBleed = false, + bleedCost = 45, + cureBurn = false, + burnCost = 30, + cureElectrify = false, + electrifyCost = 22, + cureParalyse = false, + paralyseCost = 40, + paralyseSpell = "utani hur", + holdHaste = false, + hasteCost = 40, + hasteSpell = "utani hur", + holdUtamo = false, + utamoCost = 40, + holdUtana = false, + utanaCost = 440, + holdUtura = false, + uturaType = "", + uturaCost = 100, + ignoreInPz = true, + stopHaste = false + } + end + + ui.title:setOn(HealBotConfig[conditionPanelName].enabled) + ui.title.onClick = function(widget) + HealBotConfig[conditionPanelName].enabled = not HealBotConfig[conditionPanelName].enabled + widget:setOn(HealBotConfig[conditionPanelName].enabled) + vBotConfigSave("heal") + end + + ui.conditionList.onClick = function(widget) + conditionsWindow:show() + conditionsWindow:raise() + conditionsWindow:focus() + end + + + + local rootWidget = g_ui.getRootWidget() + if rootWidget then + conditionsWindow = UI.createWindow('ConditionsWindow', rootWidget) + conditionsWindow:hide() + + -- text edits + conditionsWindow.Cure.PoisonCost:setText(HealBotConfig[conditionPanelName].poisonCost) + conditionsWindow.Cure.PoisonCost.onTextChange = function(widget, text) + HealBotConfig[conditionPanelName].poisonCost = tonumber(text) + end + + conditionsWindow.Cure.CurseCost:setText(HealBotConfig[conditionPanelName].curseCost) + conditionsWindow.Cure.CurseCost.onTextChange = function(widget, text) + HealBotConfig[conditionPanelName].curseCost = tonumber(text) + end + + conditionsWindow.Cure.BleedCost:setText(HealBotConfig[conditionPanelName].bleedCost) + conditionsWindow.Cure.BleedCost.onTextChange = function(widget, text) + HealBotConfig[conditionPanelName].bleedCost = tonumber(text) + end + + conditionsWindow.Cure.BurnCost:setText(HealBotConfig[conditionPanelName].burnCost) + conditionsWindow.Cure.BurnCost.onTextChange = function(widget, text) + HealBotConfig[conditionPanelName].burnCost = tonumber(text) + end + + conditionsWindow.Cure.ElectrifyCost:setText(HealBotConfig[conditionPanelName].electrifyCost) + conditionsWindow.Cure.ElectrifyCost.onTextChange = function(widget, text) + HealBotConfig[conditionPanelName].electrifyCost = tonumber(text) + end + + conditionsWindow.Cure.ParalyseCost:setText(HealBotConfig[conditionPanelName].paralyseCost) + conditionsWindow.Cure.ParalyseCost.onTextChange = function(widget, text) + HealBotConfig[conditionPanelName].paralyseCost = tonumber(text) + end + + conditionsWindow.Cure.ParalyseSpell:setText(HealBotConfig[conditionPanelName].paralyseSpell) + conditionsWindow.Cure.ParalyseSpell.onTextChange = function(widget, text) + HealBotConfig[conditionPanelName].paralyseSpell = text + end + + conditionsWindow.Hold.HasteSpell:setText(HealBotConfig[conditionPanelName].hasteSpell) + conditionsWindow.Hold.HasteSpell.onTextChange = function(widget, text) + HealBotConfig[conditionPanelName].hasteSpell = text + end + + conditionsWindow.Hold.HasteCost:setText(HealBotConfig[conditionPanelName].hasteCost) + conditionsWindow.Hold.HasteCost.onTextChange = function(widget, text) + HealBotConfig[conditionPanelName].hasteCost = tonumber(text) + end + + conditionsWindow.Hold.UtamoCost:setText(HealBotConfig[conditionPanelName].utamoCost) + conditionsWindow.Hold.UtamoCost.onTextChange = function(widget, text) + HealBotConfig[conditionPanelName].utamoCost = tonumber(text) + end + + conditionsWindow.Hold.UtanaCost:setText(HealBotConfig[conditionPanelName].utanaCost) + conditionsWindow.Hold.UtanaCost.onTextChange = function(widget, text) + HealBotConfig[conditionPanelName].utanaCost = tonumber(text) + end + + conditionsWindow.Hold.UturaCost:setText(HealBotConfig[conditionPanelName].uturaCost) + conditionsWindow.Hold.UturaCost.onTextChange = function(widget, text) + HealBotConfig[conditionPanelName].uturaCost = tonumber(text) + end + + -- combo box + conditionsWindow.Hold.UturaType:setOption(HealBotConfig[conditionPanelName].uturaType) + conditionsWindow.Hold.UturaType.onOptionChange = function(widget) + HealBotConfig[conditionPanelName].uturaType = widget:getCurrentOption().text + end + + -- checkboxes + conditionsWindow.Cure.CurePoison:setChecked(HealBotConfig[conditionPanelName].curePoison) + conditionsWindow.Cure.CurePoison.onClick = function(widget) + HealBotConfig[conditionPanelName].curePoison = not HealBotConfig[conditionPanelName].curePoison + widget:setChecked(HealBotConfig[conditionPanelName].curePoison) + end + + conditionsWindow.Cure.CureCurse:setChecked(HealBotConfig[conditionPanelName].cureCurse) + conditionsWindow.Cure.CureCurse.onClick = function(widget) + HealBotConfig[conditionPanelName].cureCurse = not HealBotConfig[conditionPanelName].cureCurse + widget:setChecked(HealBotConfig[conditionPanelName].cureCurse) + end + + conditionsWindow.Cure.CureBleed:setChecked(HealBotConfig[conditionPanelName].cureBleed) + conditionsWindow.Cure.CureBleed.onClick = function(widget) + HealBotConfig[conditionPanelName].cureBleed = not HealBotConfig[conditionPanelName].cureBleed + widget:setChecked(HealBotConfig[conditionPanelName].cureBleed) + end + + conditionsWindow.Cure.CureBurn:setChecked(HealBotConfig[conditionPanelName].cureBurn) + conditionsWindow.Cure.CureBurn.onClick = function(widget) + HealBotConfig[conditionPanelName].cureBurn = not HealBotConfig[conditionPanelName].cureBurn + widget:setChecked(HealBotConfig[conditionPanelName].cureBurn) + end + + conditionsWindow.Cure.CureElectrify:setChecked(HealBotConfig[conditionPanelName].cureElectrify) + conditionsWindow.Cure.CureElectrify.onClick = function(widget) + HealBotConfig[conditionPanelName].cureElectrify = not HealBotConfig[conditionPanelName].cureElectrify + widget:setChecked(HealBotConfig[conditionPanelName].cureElectrify) + end + + conditionsWindow.Cure.CureParalyse:setChecked(HealBotConfig[conditionPanelName].cureParalyse) + conditionsWindow.Cure.CureParalyse.onClick = function(widget) + HealBotConfig[conditionPanelName].cureParalyse = not HealBotConfig[conditionPanelName].cureParalyse + widget:setChecked(HealBotConfig[conditionPanelName].cureParalyse) + end + + conditionsWindow.Hold.HoldHaste:setChecked(HealBotConfig[conditionPanelName].holdHaste) + conditionsWindow.Hold.HoldHaste.onClick = function(widget) + HealBotConfig[conditionPanelName].holdHaste = not HealBotConfig[conditionPanelName].holdHaste + widget:setChecked(HealBotConfig[conditionPanelName].holdHaste) + end + + conditionsWindow.Hold.HoldUtamo:setChecked(HealBotConfig[conditionPanelName].holdUtamo) + conditionsWindow.Hold.HoldUtamo.onClick = function(widget) + HealBotConfig[conditionPanelName].holdUtamo = not HealBotConfig[conditionPanelName].holdUtamo + widget:setChecked(HealBotConfig[conditionPanelName].holdUtamo) + end + + conditionsWindow.Hold.HoldUtana:setChecked(HealBotConfig[conditionPanelName].holdUtana) + conditionsWindow.Hold.HoldUtana.onClick = function(widget) + HealBotConfig[conditionPanelName].holdUtana = not HealBotConfig[conditionPanelName].holdUtana + widget:setChecked(HealBotConfig[conditionPanelName].holdUtana) + end + + conditionsWindow.Hold.HoldUtura:setChecked(HealBotConfig[conditionPanelName].holdUtura) + conditionsWindow.Hold.HoldUtura.onClick = function(widget) + HealBotConfig[conditionPanelName].holdUtura = not HealBotConfig[conditionPanelName].holdUtura + widget:setChecked(HealBotConfig[conditionPanelName].holdUtura) + end + + conditionsWindow.Hold.IgnoreInPz:setChecked(HealBotConfig[conditionPanelName].ignoreInPz) + conditionsWindow.Hold.IgnoreInPz.onClick = function(widget) + HealBotConfig[conditionPanelName].ignoreInPz = not HealBotConfig[conditionPanelName].ignoreInPz + widget:setChecked(HealBotConfig[conditionPanelName].ignoreInPz) + end + + conditionsWindow.Hold.StopHaste:setChecked(HealBotConfig[conditionPanelName].stopHaste) + conditionsWindow.Hold.StopHaste.onClick = function(widget) + HealBotConfig[conditionPanelName].stopHaste = not HealBotConfig[conditionPanelName].stopHaste + widget:setChecked(HealBotConfig[conditionPanelName].stopHaste) + end + + -- buttons + conditionsWindow.closeButton.onClick = function(widget) + conditionsWindow:hide() + vBotConfigSave("heal") + end + end + + local utanaCast = nil + macro(500, function() + if not HealBotConfig[conditionPanelName].enabled or modules.game_cooldown.isGroupCooldownIconActive(2) then return end + if hppercent() > 95 then + if HealBotConfig[conditionPanelName].curePoison and mana() >= HealBotConfig[conditionPanelName].poisonCost and isPoisioned() then say("exana pox") + elseif HealBotConfig[conditionPanelName].cureCurse and mana() >= HealBotConfig[conditionPanelName].curseCost and isCursed() then say("exana mort") + elseif HealBotConfig[conditionPanelName].cureBleed and mana() >= HealBotConfig[conditionPanelName].bleedCost and isBleeding() then say("exana kor") + elseif HealBotConfig[conditionPanelName].cureBurn and mana() >= HealBotConfig[conditionPanelName].burnCost and isBurning() then say("exana flam") + elseif HealBotConfig[conditionPanelName].cureElectrify and mana() >= HealBotConfig[conditionPanelName].electrifyCost and isEnergized() then say("exana vis") + end + end + if (not HealBotConfig[conditionPanelName].ignoreInPz or not isInPz()) and HealBotConfig[conditionPanelName].holdUtura and mana() >= HealBotConfig[conditionPanelName].uturaCost and not hasPartyBuff() then say(HealBotConfig[conditionPanelName].uturaType) + elseif (not HealBotConfig[conditionPanelName].ignoreInPz or not isInPz()) and HealBotConfig[conditionPanelName].holdUtana and mana() >= HealBotConfig[conditionPanelName].utanaCost and (not utanaCast or (now - utanaCast > 120000)) then say("utana vid") utanaCast = now + end + end) + + macro(50, function() + if not HealBotConfig[conditionPanelName].enabled then return end + if (not HealBotConfig[conditionPanelName].ignoreInPz or not isInPz()) and HealBotConfig[conditionPanelName].holdUtamo and mana() >= HealBotConfig[conditionPanelName].utamoCost and not hasManaShield() then say("utamo vita") + elseif (not HealBotConfig[conditionPanelName].ignoreInPz or not isInPz()) and HealBotConfig[conditionPanelName].holdHaste and mana() >= HealBotConfig[conditionPanelName].hasteCost and not hasHaste() and not getSpellCoolDown(HealBotConfig[conditionPanelName].hasteSpell) and (not target() or not HealBotConfig[conditionPanelName].stopHaste or TargetBot.isCaveBotActionAllowed()) then say(HealBotConfig[conditionPanelName].hasteSpell) + elseif HealBotConfig[conditionPanelName].cureParalyse and mana() >= HealBotConfig[conditionPanelName].paralyseCost and isParalyzed() and not getSpellCoolDown(HealBotConfig[conditionPanelName].paralyseSpell) then say(HealBotConfig[conditionPanelName].paralyseSpell) + end + end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/Conditions.otui b/modules/game_bot/default_configs/vBot_2.01/vBot/Conditions.otui similarity index 99% rename from modules/game_bot/default_configs/vBot/Conditions.otui rename to modules/game_bot/default_configs/vBot_2.01/vBot/Conditions.otui index eadf1f9..38762e2 100644 --- a/modules/game_bot/default_configs/vBot/Conditions.otui +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/Conditions.otui @@ -377,7 +377,6 @@ HoldConditions < Panel ConditionsWindow < MainWindow !text: tr('Condition Manager') size: 445 280 - @onEscape: self:hide() CureConditions id: Cure diff --git a/modules/game_bot/default_configs/vBot/2HealBot.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/HealBot.lua similarity index 93% rename from modules/game_bot/default_configs/vBot/2HealBot.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/HealBot.lua index fbe928c..2663963 100644 --- a/modules/game_bot/default_configs/vBot/2HealBot.lua +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/HealBot.lua @@ -75,8 +75,8 @@ Panel ]]) ui:setId(healPanelName) -if not storage[healPanelName] or not storage[healPanelName][1] or #storage[healPanelName] ~= 5 then - storage[healPanelName] = { +if not HealBotConfig[healPanelName] or not HealBotConfig[healPanelName][1] or #HealBotConfig[healPanelName] ~= 5 then + HealBotConfig[healPanelName] = { [1] = { enabled = false, spellTable = {}, @@ -140,21 +140,21 @@ if not storage[healPanelName] or not storage[healPanelName][1] or #storage[healP } end -if not storage.currentHealBotProfile or storage.currentHealBotProfile == 0 or storage.currentHealBotProfile > 5 then - storage.currentHealBotProfile = 1 +if not HealBotConfig.currentHealBotProfile or HealBotConfig.currentHealBotProfile == 0 or HealBotConfig.currentHealBotProfile > 5 then + HealBotConfig.currentHealBotProfile = 1 end -- finding correct table, manual unfortunately local currentSettings local setActiveProfile = function() - local n = storage.currentHealBotProfile - currentSettings = storage[healPanelName][n] + local n = HealBotConfig.currentHealBotProfile + currentSettings = HealBotConfig[healPanelName][n] end setActiveProfile() local activeProfileColor = function() for i=1,5 do - if i == storage.currentHealBotProfile then + if i == HealBotConfig.currentHealBotProfile then ui[i]:setColor("green") else ui[i]:setColor("white") @@ -167,6 +167,7 @@ ui.title:setOn(currentSettings.enabled) ui.title.onClick = function(widget) currentSettings.enabled = not currentSettings.enabled widget:setOn(currentSettings.enabled) +vBotConfigSave("heal") end ui.settings.onClick = function(widget) @@ -177,7 +178,7 @@ end rootWidget = g_ui.getRootWidget() if rootWidget then - healWindow = g_ui.createWidget('HealWindow', rootWidget) + healWindow = UI.createWindow('HealWindow', rootWidget) healWindow:hide() local setProfileName = function() @@ -218,7 +219,7 @@ if rootWidget then child:destroy() end for _, entry in pairs(currentSettings.spellTable) do - local label = g_ui.createWidget("SpellEntry", healWindow.spells.spellList) + local label = UI.createWidget("SpellEntry", healWindow.spells.spellList) label.enabled:setChecked(entry.enabled) label.enabled.onClick = function(widget) entry.enabled = not entry.enabled @@ -241,7 +242,7 @@ if rootWidget then child:destroy() end for _, entry in pairs(currentSettings.itemTable) do - local label = g_ui.createWidget("SpellEntry", healWindow.items.itemList) + local label = UI.createWidget("SpellEntry", healWindow.items.itemList) label.enabled:setChecked(entry.enabled) label.enabled.onClick = function(widget) entry.enabled = not entry.enabled @@ -462,6 +463,7 @@ if rootWidget then healWindow.closeButton.onClick = function(widget) healWindow:hide() + vBotConfigSave("heal") end local loadSettings = function() @@ -483,6 +485,7 @@ if rootWidget then setActiveProfile() activeProfileColor() loadSettings() + vBotConfigSave("heal") end local resetSettings = function() @@ -495,14 +498,14 @@ if rootWidget then currentSettings.MessageDelay = false currentSettings.Interval = true currentSettings.Conditions = true - currentSettings.name = "Profile #" .. storage.currentBotProfile + currentSettings.name = "Profile #" .. HealBotConfig.currentBotProfile end -- profile buttons for i=1,5 do local button = ui[i] button.onClick = function() - storage.currentHealBotProfile = i + HealBotConfig.currentHealBotProfile = i profileChange() end end @@ -527,22 +530,24 @@ if rootWidget then HealBot.setOff = function() currentSettings.enabled = false ui.title:setOn(currentSettings.enabled) + vBotConfigSave("atk") end HealBot.setOn = function() currentSettings.enabled = true ui.title:setOn(currentSettings.enabled) + vBotConfigSave("atk") end HealBot.getActiveProfile = function() - return storage.currentHealBotProfile -- returns number 1-5 + return HealBotConfig.currentHealBotProfile -- returns number 1-5 end HealBot.setActiveProfile = function(n) if not n or not tonumber(n) or n < 1 or n > 5 then return error("[HealBot] wrong profile parameter! should be 1 to 5 is " .. n) else - storage.currentHealBotProfile = n + HealBotConfig.currentHealBotProfile = n profileChange() end end @@ -553,7 +558,7 @@ macro(100, function() if not currentSettings.enabled or modules.game_cooldown.isGroupCooldownIconActive(2) or #currentSettings.spellTable == 0 then return end for _, entry in pairs(currentSettings.spellTable) do - if canCast(entry.spell, not currentSettings.Conditions, currentSettings.Cooldown) and entry.enabled and entry.cost < mana() then + if canCast(entry.spell, not currentSettings.Conditions, not currentSettings.Cooldown) and entry.enabled and entry.cost < mana() then if entry.origin == "HP%" then if entry.sign == "=" and hppercent() == entry.value then say(entry.spell) @@ -617,8 +622,8 @@ end) -- items macro(100, function() if not currentSettings.enabled or #currentSettings.itemTable == 0 then return end - if currentSettings.Delay and storage.isUsing then return end - if currentSettings.MessageDelay and storage.isUsingPotion then return end + if currentSettings.Delay and HealBotConfig.isUsing then return end + if currentSettings.MessageDelay and HealBotConfig.isUsingPotion then return end if not currentSettings.MessageDelay then delay(400) diff --git a/modules/game_bot/default_configs/vBot/HealBot.otui b/modules/game_bot/default_configs/vBot_2.01/vBot/HealBot.otui similarity index 99% rename from modules/game_bot/default_configs/vBot/HealBot.otui rename to modules/game_bot/default_configs/vBot_2.01/vBot/HealBot.otui index 4f45c9e..06a197a 100644 --- a/modules/game_bot/default_configs/vBot/HealBot.otui +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/HealBot.otui @@ -285,7 +285,6 @@ ItemHealing < Panel HealWindow < MainWindow !text: tr('Self Healer') size: 800 350 - @onEscape: self:hide() SpellHealing id: spells diff --git a/modules/game_bot/default_configs/vBot/3_Sio.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/Sio.lua similarity index 98% rename from modules/game_bot/default_configs/vBot/3_Sio.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/Sio.lua index 7a1133d..58d7dfb 100644 --- a/modules/game_bot/default_configs/vBot/3_Sio.lua +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/Sio.lua @@ -38,7 +38,7 @@ Panel rootWidget = g_ui.getRootWidget() - sioListWindow = g_ui.createWidget('SioListWindow', rootWidget) + sioListWindow = UI.createWindow('SioListWindow', rootWidget) sioListWindow:hide() ui.title:setOn(storage[panelName].enabled) diff --git a/modules/game_bot/default_configs/vBot/1_alarms.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/alarms.lua similarity index 98% rename from modules/game_bot/default_configs/vBot/1_alarms.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/alarms.lua index 27182ca..8eed9e1 100644 --- a/modules/game_bot/default_configs/vBot/1_alarms.lua +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/alarms.lua @@ -46,7 +46,7 @@ end rootWidget = g_ui.getRootWidget() if rootWidget then - alarmsWindow = g_ui.createWidget('AlarmsWindow', rootWidget) + alarmsWindow = UI.createWindow('AlarmsWindow', rootWidget) alarmsWindow:hide() alarmsWindow.closeButton.onClick = function(widget) diff --git a/modules/game_bot/default_configs/vBot/alarms.otui b/modules/game_bot/default_configs/vBot_2.01/vBot/alarms.otui similarity index 100% rename from modules/game_bot/default_configs/vBot/alarms.otui rename to modules/game_bot/default_configs/vBot_2.01/vBot/alarms.otui diff --git a/modules/game_bot/default_configs/vBot/z_antiRs.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/antiRs.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/z_antiRs.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/antiRs.lua diff --git a/modules/game_bot/default_configs/vBot/_cavebot.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/cavebot.lua similarity index 89% rename from modules/game_bot/default_configs/vBot/_cavebot.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/cavebot.lua index 7e9040b..76700e5 100644 --- a/modules/game_bot/default_configs/vBot/_cavebot.lua +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/cavebot.lua @@ -5,12 +5,10 @@ local cavebotTab = "Cave" local targetingTab = "Target" setDefaultTab(cavebotTab) -CaveBot = {} -- global namespace CaveBot.Extensions = {} importStyle("/cavebot/cavebot.otui") importStyle("/cavebot/config.otui") importStyle("/cavebot/editor.otui") -importStyle("/cavebot/supply.otui") dofile("/cavebot/actions.lua") dofile("/cavebot/config.lua") dofile("/cavebot/editor.lua") @@ -23,8 +21,6 @@ dofile("/cavebot/sell_all.lua") dofile("/cavebot/depositor.lua") dofile("/cavebot/buy_supplies.lua") dofile("/cavebot/d_withdraw.lua") -dofile("/cavebot/depositer.lua") -dofile("/cavebot/supply.lua") dofile("/cavebot/supply_check.lua") dofile("/cavebot/travel.lua") dofile("/cavebot/doors.lua") @@ -33,8 +29,6 @@ dofile("/cavebot/withdraw.lua") dofile("/cavebot/inbox_withdraw.lua") dofile("/cavebot/lure.lua") dofile("/cavebot/bank.lua") -dofile("/cavebot/depositer.lua") -dofile("/cavebot/supply.lua") dofile("/cavebot/clear_tile.lua") dofile("/cavebot/tasker.lua") -- main cavebot file, must be last diff --git a/modules/game_bot/default_configs/vBot/1_combo.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/combo.lua similarity index 99% rename from modules/game_bot/default_configs/vBot/1_combo.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/combo.lua index 641f495..dcfccf0 100644 --- a/modules/game_bot/default_configs/vBot/1_combo.lua +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/combo.lua @@ -1,3 +1,4 @@ +setDefaultTab("Main") ComboPanelName = "combobot" local ui = setupUI([[ Panel @@ -63,7 +64,7 @@ end rootWidget = g_ui.getRootWidget() if rootWidget then - comboWindow = g_ui.createWidget('ComboWindow', rootWidget) + comboWindow = UI.createWindow('ComboWindow', rootWidget) comboWindow:hide() -- bot item diff --git a/modules/game_bot/default_configs/vBot/combo.otui b/modules/game_bot/default_configs/vBot_2.01/vBot/combo.otui similarity index 100% rename from modules/game_bot/default_configs/vBot/combo.otui rename to modules/game_bot/default_configs/vBot_2.01/vBot/combo.otui diff --git a/modules/game_bot/default_configs/vBot_2.01/vBot/configs.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/configs.lua new file mode 100644 index 0000000..c2dc22b --- /dev/null +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/configs.lua @@ -0,0 +1,82 @@ +-- [[ test config part ]] -- +configName = modules.game_bot.contentsPanel.config:getCurrentOption().text + +-- make vBot config dir +if not g_resources.directoryExists("/bot/".. configName .."/vBot_configs/") then + g_resources.makeDir("/bot/".. configName .."/vBot_configs/") +end + +HealBotConfig = {} +local healBotFile = "/bot/" .. configName .. "/vBot_configs/".. name() .. " HealBot.json" +AttackBotConfig = {} +local attackBotFile = "/bot/" .. configName .. "/vBot_configs/".. name() .. " AttackBot.json" +SuppliesConfig = {} +local suppliesFile = "/bot/" .. configName .. "/vBot_configs/".. name() .. " Supplies.json" + + +--healbot +if g_resources.fileExists(healBotFile) then + local status, result = pcall(function() + return json.decode(g_resources.readFileContents(healBotFile)) + end) + if not status then + return onError("Error while reading config file (" .. healBotFile .. "). To fix this problem you can delete HealBot.json. Details: " .. result) + end + HealBotConfig = result +end + +--attackbot +if g_resources.fileExists(attackBotFile) then + local status, result = pcall(function() + return json.decode(g_resources.readFileContents(attackBotFile)) + end) + if not status then + return onError("Error while reading config file (" .. attackBotFile .. "). To fix this problem you can delete HealBot.json. Details: " .. result) + end + AttackBotConfig = result +end + +--supplies +if g_resources.fileExists(suppliesFile) then + local status, result = pcall(function() + return json.decode(g_resources.readFileContents(suppliesFile)) + end) + if not status then + return onError("Error while reading config file (" .. suppliesFile .. "). To fix this problem you can delete HealBot.json. Details: " .. result) + end + SuppliesConfig = result +end + +function vBotConfigSave(file) + -- file can be either + --- heal + --- atk + --- supply + local configFile + local configTable + if not file then return end + file = file:lower() + if file == "heal" then + configFile = healBotFile + configTable = HealBotConfig + elseif file == "atk" then + configFile = attackBotFile + configTable = AttackBotConfig + elseif file == "supply" then + configFile = suppliesFile + configTable = SuppliesConfig + end + + local status, result = pcall(function() + return json.encode(configTable, 2) + end) + if not status then + return onError("Error while saving config. it won't be saved. Details: " .. result) + end + + if result:len() > 100 * 1024 * 1024 then + return onError("config file is too big, above 100MB, it won't be saved") + end + + g_resources.writeFileContents(configFile, result) +end \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/z_depot_withdraw.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/depot_withdraw.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/z_depot_withdraw.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/depot_withdraw.lua diff --git a/modules/game_bot/default_configs/vBot/eat_food.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/eat_food.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/eat_food.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/eat_food.lua diff --git a/modules/game_bot/default_configs/vBot/equip.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/equip.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/equip.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/equip.lua diff --git a/modules/game_bot/default_configs/vBot/exeta.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/exeta.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/exeta.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/exeta.lua diff --git a/modules/game_bot/default_configs/vBot_2.01/vBot/extras.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/extras.lua new file mode 100644 index 0000000..85ffa8b --- /dev/null +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/extras.lua @@ -0,0 +1,434 @@ +setDefaultTab("Main") + +-- securing storage namespace +panelName = "extras" +if not storage[panelName] then + storage[panelName] = {} +end +local settings = storage[panelName] + +-- basic elements +extrasWindow = UI.createWindow('ExtrasWindow', rootWidget) +extrasWindow:hide() +extrasWindow.closeButton.onClick = function(widget) + extrasWindow:hide() +end + +-- available options for dest param +local rightPanel = extrasWindow.content.right +local leftPanel = extrasWindow.content.left + +-- objects made by Kondrah - taken from creature editor, minor changes to adapt +local addCheckBox = function(id, title, defaultValue, dest) + local widget = UI.createWidget('ExtrasCheckBox', dest) + widget.onClick = function() + widget:setOn(not widget:isOn()) + settings[id] = widget:isOn() + end + widget:setText(title) + if settings[id] == nil then + widget:setOn(defaultValue) + else + widget:setOn(settings[id]) + end + settings[id] = widget:isOn() +end + +local addItem = function(id, title, defaultItem, dest) + local widget = UI.createWidget('ExtrasItem', dest) + widget.text:setText(title) + widget.item:setItemId(settings[id] or defaultItem) + widget.item.onItemChange = function(widget) + settings[id] = widget:getItemId() + end + settings[id] = settings[id] or defaultItem +end + +local addTextEdit = function(id, title, defaultValue, dest) + local widget = UI.createWidget('ExtrasTextEdit', dest) + widget.text:setText(title) + widget.textEdit:setText(settings[id] or defaultValue or "") + widget.textEdit.onTextChange = function(widget,text) + settings[id] = text + end + settings[id] = settings[id] or defaultValue or "" +end + +local addScrollBar = function(id, title, min, max, defaultValue, dest) + local widget = UI.createWidget('ExtrasScrollBar', dest) + widget.scroll.onValueChange = function(scroll, value) + widget.text:setText(title .. ": " .. value) + if value == 0 then + value = 1 + end + settings[id] = value + end + widget.scroll:setRange(min, max) + if max-min > 1000 then + widget.scroll:setStep(100) + elseif max-min > 100 then + widget.scroll:setStep(10) + end + widget.scroll:setValue(settings[id] or defaultValue) + widget.scroll.onValueChange(widget.scroll, widget.scroll:getValue()) +end + +UI.Button("vBot Settings and Scripts", function() + extrasWindow:show() + extrasWindow:raise() + extrasWindow:focus() +end) +UI.Separator() + +-- to remain order, add options right after another: +--- add object +--- add variables for function (optional) +--- add callback (optional) +--- optionals should be addionaly sandboxed (if true then end) + +addItem("rope", "Rope Item", 9596, leftPanel) +addItem("shovel", "Shovel Item", 9596, leftPanel) +addItem("machete", "Machete Item", 9596, leftPanel) +addItem("scythe", "Scythe Item", 9596, leftPanel) +addScrollBar("talkDelay", "Global NPC Talk Delay", 0, 2000, 1000, leftPanel) +addScrollBar("looting", "Max Loot Distance", 0, 50, 40, leftPanel) + +addCheckBox("title", "Custom Window Title", true, rightPanel) +if true then + local vocText = "" + + if voc() == 1 or voc() == 11 then + vocText = "- EK" + elseif voc() == 2 or voc() == 12 then + vocText = "- RP" + elseif voc() == 3 or voc() == 13 then + vocText = "- MS" + elseif voc() == 4 or voc() == 14 then + vocText = "- ED" + end + + macro(2000, function() + if settings.title then + if hppercent() > 0 then + g_window.setTitle("Tibia - " .. name() .. " - " .. lvl() .. "lvl " .. vocText) + else + g_window.setTitle("Tibia - " .. name() .. " - DEAD") + end + else + g_window.setTitle("Tibia - " .. name()) + end + end) +end + + +addTextEdit("useAll", "Use All Hotkey", "space", rightPanel) +if true then + local useId = {34847, 1764, 21051, 30823, 6264, 5282, 20453, 20454, 20474, 11708, 11705, + 6257, 6256, 2772, 27260, 2773, 1632, 1633, 1948, 435, 6252, 6253, 5007, 4911, + 1629, 1630, 5108, 5107, 5281, 1968, 435, 1948, 5542, 31116, 31120, 30742, 31115, + 31118, 20474, 5737, 5736, 5734, 5733, 31202, 31228, 31199, 31200, 33262, 30824, + 5125, 5126, 5116, 5117, 8257, 8258, 8255, 8256} + local shovelId = {606, 593, 867} + local ropeId = {17238, 12202, 12935, 386, 421, 21966, 14238} + local macheteId = {2130, 3696} + local scytheId = {3653} + + setDefaultTab("Tools") + -- script + if settings.useAll and settings.useAll:len() > 0 then + hotkey(settings.useAll, function() + if not modules.game_walking.wsadWalking then return end + for _, tile in pairs(g_map.getTiles(posz())) do + if distanceFromPlayer(tile:getPosition()) < 2 then + for _, item in pairs(tile:getItems()) do + -- use + if table.find(useId, item:getId()) then + use(item) + return + elseif table.find(shovelId, item:getId()) then + useWith(settings.shovel, item) + return + elseif table.find(ropeId, item:getId()) then + useWith(settings.rope, item) + return + elseif table.find(macheteId, item:getId()) then + useWith(settings.machete, item) + return + elseif table.find(scytheId, item:getId()) then + useWith(settings.scythe, item) + return + end + end + end + end + end) + end +end + + +addCheckBox("timers", "MW & WG Timers", true, rightPanel) +if true then + local activeTimers = {} + + onAddThing(function(tile, thing) + if not settings.timers then return end + if not thing:isItem() then + return + end + local timer = 0 + if thing:getId() == 2129 then -- mwall id + timer = 20000 -- mwall time + elseif thing:getId() == 2130 then -- wg id + timer = 45000 -- wg time + else + return + end + + local pos = tile:getPosition().x .. "," .. tile:getPosition().y .. "," .. tile:getPosition().z + if not activeTimers[pos] or activeTimers[pos] < now then + activeTimers[pos] = now + timer + end + tile:setTimer(activeTimers[pos] - now) + end) + + onRemoveThing(function(tile, thing) + if not settings.timers then return end + if not thing:isItem() then + return + end + if (thing:getId() == 2129 or thing:getId() == 2130) and tile:getGround() then + local pos = tile:getPosition().x .. "," .. tile:getPosition().y .. "," .. tile:getPosition().z + activeTimers[pos] = nil + tile:setTimer(0) + end + end) +end + + +addCheckBox("antiKick", "Anti - Kick", true, rightPanel) +if true then + macro(60*1000, function() + if not settings.antiKick then return end + local dir = player:getDirection() + turn((dir + 1) % 4) + schedule(50, function() turn(dir) end) + end) +end + + +addCheckBox("stake", "Skin Monsters", false, leftPanel) +if true then + local knifeBodies = {4272, 4173, 4011, 4025, 4047, 4052, 4057, 4062, 4112, 4212, 4321, 4324, 4327, 10352, 10356, 10360, 10364} + local stakeBodies = {4097, 4137, 8738, 18958} + local fishingBodies = {9582} + macro(500, function() + if not CaveBot.isOn() or not settings.stake then return end + for i, tile in ipairs(g_map.getTiles(posz())) do + for u,item in ipairs(tile:getItems()) do + if table.find(knifeBodies, item:getId()) and findItem(5908) then + CaveBot.delay(550) + useWith(5908, item) + return + end + if table.find(stakeBodies, item:getId()) and findItem(5942) then + CaveBot.delay(550) + useWith(5942, item) + return + end + if table.find(fishingBodies, item:getId()) and findItem(3483) then + CaveBot.delay(550) + useWith(3483, item) + return + end + end + end + end) +end + + +addCheckBox("oberon", "Auto Reply Oberon", true, rightPanel) +if true then + onTalk(function(name, level, mode, text, channelId, pos) + if not settings.oberon then return end + if mode == 34 then + if string.find(text, "world will suffer for") then + say("Are you ever going to fight or do you prefer talking!") + elseif string.find(text, "feet when they see me") then + say("Even before they smell your breath?") + elseif string.find(text, "from this plane") then + say("Too bad you barely exist at all!") + elseif string.find(text, "ESDO LO") then + say("SEHWO ASIMO, TOLIDO ESD") + elseif string.find(text, "will soon rule this world") then + say("Excuse me but I still do not get the message!") + elseif string.find(text, "honourable and formidable") then + say("Then why are we fighting alone right now?") + elseif string.find(text, "appear like a worm") then + say("How appropriate, you look like something worms already got the better of!") + elseif string.find(text, "will be the end of mortal") then + say("Then let me show you the concept of mortality before it!") + elseif string.find(text, "virtues of chivalry") then + say("Dare strike up a Minnesang and you will receive your last accolade!") + end + end + end) +end + + +addCheckBox("autoOpenDoors", "Auto Open Doors", true, rightPanel) +if true then + local wsadWalking = modules.game_walking.wsadWalking + local doorsIds = { 5007, 8265, 1629, 1632, 5129, 6252, 6249, 7715, 7712, 7714, + 7719, 6256, 1669, 1672, 5125, 5115, 5124, 17701, 17710, 1642, + 6260, 5107, 4912, 6251, 5291, 1683, 1696, 1692, 5006, 2179, 5116, + 1632, 11705, 30772, 30774, 6248, 5735, 5732 } + + function checkForDoors(pos) + local tile = g_map.getTile(pos) + if tile then + local useThing = tile:getTopUseThing() + if useThing and table.find(doorsIds, useThing:getId()) then + g_game.use(useThing) + end + end + end + + onKeyPress(function(keys) + if not settings.autoOpenDoors then return end + local pos = player:getPosition() + if keys == 'Up' or (wsadWalking and keys == 'W') then + pos.y = pos.y - 1 + elseif keys == 'Down' or (wsadWalking and keys == 'S') then + pos.y = pos.y + 1 + elseif keys == 'Left' or (wsadWalking and keys == 'A') then + pos.x = pos.x - 1 + elseif keys == 'Right' or (wsadWalking and keys == 'D') then + pos.x = pos.x + 1 + elseif wsadWalking and keys == "Q" then + pos.y = pos.y - 1 + pos.x = pos.x - 1 + elseif wsadWalking and keys == "E" then + pos.y = pos.y - 1 + pos.x = pos.x + 1 + elseif wsadWalking and keys == "Z" then + pos.y = pos.y + 1 + pos.x = pos.x - 1 + elseif wsadWalking and keys == "C" then + pos.y = pos.y + 1 + pos.x = pos.x + 1 + end + checkForDoors(pos) + end) +end + + +addCheckBox("bless", "Buy bless at login", true, rightPanel) +if true then + if settings.bless then + if player:getBlessings() == 0 then + say("!bless") + schedule(2000, function() + if g_game.getClientVersion() > 1000 then + if player:getBlessings() == 0 then + warn("!! Blessings not bought !!") + end + end + end) + end + end +end + + +addCheckBox("reUse", "Keep Crosshair", false, rightPanel) +if true then + local excluded = {268, 237, 238, 23373, 266, 236, 239, 7643, 23375, 7642, 23374, 5908, 5942} + + onUseWith(function(pos, itemId, target, subType) + if settings.reUse and not table.find(excluded, itemId) then + schedule(50, function() + item = findItem(itemId) + if item then + modules.game_interface.startUseWith(item) + end + end) + end + end) +end + + +addCheckBox("suppliesControl", "TargetBot off if low supply", false, leftPanel) +if true then + macro(500, function() + if not settings.suppliesControl then return end + if TargetBot.isOff() then return end + if CaveBot.isOff() then return end + if not hasSupplies() then + TargetBot.setOff() + end + end) +end + +addCheckBox("holdMwall", "Hold MW/WG [ , ][ . ]", true, rightPanel) +if true then + local mwHot = "," + local wgHot = "." + + local candidates = {} + + local m = macro(20, function() + if not settings.holdMwall then return end + if #candidates == 0 then return end + + for i, tile in pairs(candidates) do + if tile:getText():len() == 0 then + table.remove(candidates, i) + end + local rune = tile:getText() == "HOLD MW" and 3180 or 3156 + if tile:canShoot() and not isInPz() and tile:isWalkable() and tile:getTopUseThing():getId() ~= 2130 then + return useWith(rune, tile:getTopUseThing()) + end + end + end) + + onRemoveThing(function(tile, thing) + if not settings.holdMwall then return end + if thing:getId() ~= 2129 then return end + if tile:getText():len() > 0 then + table.insert(candidates, tile) + useWith(3180, tile:getTopUseThing()) + end + end) + + onAddThing(function(tile, thing) + if not settings.holdMwall then return end + if m.isOff() then return end + if thing:getId() ~= 2129 then return end + if tile:getText():len() > 0 then + table.remove(candidates, table.find(candidates,tile)) + end + end) + + onKeyPress(function(keys) + local wsadWalking = modules.game_walking.wsadWalking + if not wsadWalking then return end + if not settings.holdMwall then return end + if m.isOff() then return end + if keys ~= mwHot and keys ~= wgHot then return end + + + local tile = getTileUnderCursor() + if not tile then return end + + if tile:getText():len() > 0 then + tile:setText("") + else + if keys == mwHot then + tile:setText("HOLD MW") + else + tile:setText("HOLD WG") + end + table.insert(candidates, tile) + end + end) +end + diff --git a/modules/game_bot/default_configs/vBot_2.01/vBot/extras.otui b/modules/game_bot/default_configs/vBot_2.01/vBot/extras.otui new file mode 100644 index 0000000..8a0406f --- /dev/null +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/extras.otui @@ -0,0 +1,147 @@ +ExtrasScrollBar < Panel + height: 28 + margin-top: 3 + + Label + id: text + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + text-align: center + + HorizontalScrollBar + id: scroll + anchors.left: parent.left + anchors.right: parent.right + anchors.top: prev.bottom + margin-top: 3 + minimum: 0 + maximum: 10 + step: 1 + +ExtrasTextEdit < Panel + height: 40 + margin-top: 7 + + Label + id: text + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + text-align: center + + TextEdit + id: textEdit + anchors.left: parent.left + anchors.right: parent.right + anchors.top: prev.bottom + margin-top: 5 + minimum: 0 + maximum: 10 + step: 1 + +ExtrasItem < Panel + height: 34 + margin-top: 7 + margin-left: 25 + margin-right: 25 + + Label + id: text + anchors.left: parent.left + anchors.verticalCenter: next.verticalCenter + + BotItem + id: item + anchors.top: parent.top + anchors.right: parent.right + + +ExtrasCheckBox < BotSwitch + height: 20 + margin-top: 7 + +ExtrasWindow < MainWindow + !text: tr('Extras') + size: 440 360 + padding: 25 + + Label + anchors.left: parent.left + anchors.right: parent.horizontalCenter + anchors.top: parent.top + text-align: center + text: < CaveBot > + + Label + anchors.left: parent.horizontalCenter + anchors.right: parent.right + anchors.top: parent.top + text-align: center + text: < Miscellaneous > + + VerticalScrollBar + id: contentScroll + anchors.top: prev.bottom + margin-top: 3 + anchors.right: parent.right + anchors.bottom: separator.top + step: 28 + pixels-scroll: true + margin-right: -10 + margin-top: 5 + margin-bottom: 5 + + ScrollablePanel + id: content + anchors.top: prev.top + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: separator.top + vertical-scrollbar: contentScroll + margin-bottom: 10 + + Panel + id: left + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.horizontalCenter + margin-top: 5 + margin-left: 10 + margin-right: 10 + layout: + type: verticalBox + fit-children: true + + Panel + id: right + anchors.top: parent.top + anchors.left: parent.horizontalCenter + anchors.right: parent.right + margin-top: 5 + margin-left: 10 + margin-right: 10 + layout: + type: verticalBox + fit-children: true + + VerticalSeparator + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.horizontalCenter + + HorizontalSeparator + id: separator + anchors.right: parent.right + anchors.left: parent.left + anchors.bottom: closeButton.top + margin-bottom: 8 + + Button + id: closeButton + !text: tr('Close') + font: cipsoftFont + anchors.right: parent.right + anchors.bottom: parent.bottom + size: 45 21 + margin-right: 5 \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/z_info.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/info.lua similarity index 93% rename from modules/game_bot/default_configs/vBot/z_info.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/info.lua index 8fca82f..9811fb0 100644 --- a/modules/game_bot/default_configs/vBot/z_info.lua +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/info.lua @@ -1,5 +1,4 @@ setDefaultTab("Main") - -- first, the variables local launchTime = now local startExp = exp() @@ -202,20 +201,31 @@ macro(500, function() end end) -UI.Label("Session Analyzers") -UI.Separator() -UI.Button("Reset Session", function() resetSessionData() end) -UI.Separator() - -- visuals local ui = setupUI([[ Panel - height: 270 + height: 320 padding: 5 + BotButton + id: toggle + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + text: Session Analyzer + + BotButton + id: reset + anchors.top: prev.bottom + margin-top: 5 + anchors.left: parent.left + anchors.right: parent.right + text: Reset Session + Label id: SessionLabel - anchors.top: parent.top + anchors.top: prev.bottom + margin-top: 3 anchors.left: parent.left text: Session: @@ -430,6 +440,24 @@ Panel ]]) ui:setId("analyzers") +local function toggleHeight() + local h = ui:getHeight() + + if h == 320 then + ui:setHeight(28) + else + ui:setHeight(320) + end +end +toggleHeight() + +ui.reset.onClick = function(widget) + resetSessionData() +end +ui.toggle.onClick = function(widget) + toggleHeight() +end + macro(500, function() -- refresh part ui.one:setText(sessionTime()) diff --git a/modules/game_bot/default_configs/vBot_2.01/vBot/ingame_editor.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/ingame_editor.lua new file mode 100644 index 0000000..1217b82 --- /dev/null +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/ingame_editor.lua @@ -0,0 +1,23 @@ +setDefaultTab("Tools") +-- allows to test/edit bot lua scripts ingame, you can have multiple scripts like this, just change storage.ingame_lua +UI.Button("Ingame script editor", function(newText) + UI.MultilineEditorWindow(storage.ingame_hotkeys or "", {title="Hotkeys editor", description="You can add your custom scrupts here"}, function(text) + storage.ingame_hotkeys = text + reload() + end) + end) + + UI.Separator() + + for _, scripts in pairs({storage.ingame_hotkeys}) do + if type(scripts) == "string" and scripts:len() > 3 then + local status, result = pcall(function() + assert(load(scripts, "ingame_editor"))() + end) + if not status then + error("Ingame edior error:\n" .. result) + end + end + end + + UI.Separator() \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_2.01/vBot/items.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/items.lua new file mode 100644 index 0000000..6f6cf68 --- /dev/null +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/items.lua @@ -0,0 +1,1234 @@ +LootItems = { + ["gold coin"] = 1, + ["platinum coin"] = 100, + ["crystal coin"] = 10000, + ["abyss hammer"] = 20000, + ["acorn"] = 10, + ["albino plate"] = 1500, + ["alloy legs"] = 11000, + ["alptramun's toothbrush"] = 270000, + ["amber"] = 20000, + ["amber staff"] = 8000, + ["amber with a bug"] = 41000, + ["amber with a dragonfly"] = 56000, + ["ancient amulet"] = 200, + ["ancient belt buckle"] = 260, + ["ancient coin"] = 350, + ["ancient liche bone"] = 28000, + ["ancient shield"] = 900, + ["ancient stone"] = 200, + ["angel figurine"] = 36000, + ["angelic axe"] = 5000, + ["ankh"] = 100, + ["antlers"] = 50, + ["ape fur"] = 120, + ["apron"] = 1300, + ["arbalest"] = 42000, + ["arcane staff"] = 42000, + ["assassin dagger"] = 20000, + ["axe"] = 7, + ["axe ring"] = 100, + ["baby seal doll"] = 20000, + ["badger boots"] = 7500, + ["badger fur"] = 15, + ["bamboo stick"] = 30, + ["banana sash"] = 55, + ["banana staff"] = 1000, + ["bandana"] = 150, + ["bar of gold"] = 10000, + ["basalt fetish"] = 210, + ["basalt figurine"] = 160, + ["bast skirt"] = 750, + ["bat decoration"] = 2000, + ["bat wing"] = 50, + ["battle axe"] = 80, + ["battle hammer"] = 120, + ["battle shield"] = 95, + ["battle stone"] = 290, + ["batwing hat"] = 8000, + ["bear paw"] = 100, + ["beast's nightmare-cushion"] = 630000, + ["beastslayer axe"] = 1500, + ["bed of nails"] = 500, + ["beer tap"] = 50, + ["beetle carapace"] = 200, + ["beetle necklace"] = 1500, + ["behemoth claw"] = 2000, + ["behemoth trophy"] = 20000, + ["bejeweled ship's telescope"] = 20000, + ["berserk potion"] = 500, + ["berserker"] = 40000, + ["black hood"] = 190, + ["black pearl"] = 280, + ["black shield"] = 800, + ["black wool"] = 300, + ["blacksteel sword"] = 6000, + ["blade of corruption"] = 60000, + ["blazing bone"] = 610, + ["blessed sceptre"] = 40000, + ["blood preservation"] = 320, + ["blood tincture in a vial"] = 360, + ["bloody dwarven beard"] = 110, + ["bloody edge"] = 30000, + ["bloody pincers"] = 100, + ["bloody tears"] = 70000, + ["blue crystal shard"] = 1500, + ["blue crystal splinter"] = 400, + ["blue gem"] = 5000, + ["blue glass plate"] = 60, + ["blue goanna scale"] = 230, + ["blue legs"] = 15000, + ["blue piece of cloth"] = 200, + ["blue robe"] = 10000, + ["blue rose"] = 250, + ["boggy dreads"] = 200, + ["bola"] = 35, + ["bone club"] = 5, + ["bone fetish"] = 150, + ["bone shield"] = 80, + ["bone shoulderplate"] = 150, + ["bone sword"] = 20, + ["bone toothpick"] = 150, + ["bonebeast trophy3"] = 6000, + ["bonebreaker"] = 10000, + ["bonecarving knife"] = 190, + ["bonelord eye"] = 80, + ["bonelord helmet"] = 2200, + ["bonelord shield"] = 1200, + ["bones of zorvorax"] = 10000, + ["bony tail"] = 210, + ["book of necromantic rituals"] = 180, + ["book of prayers"] = 120, + ["book page"] = 640, + ["boots of haste"] = 30000, + ["bow"] = 100, + ["bowl of terror sweat"] = 500, + ["brain head's giant neuron"] = 100000, + ["brain head's left hemisphere"] = 90000, + ["brain head's right hemisphere"] = 50000, + ["brass armor"] = 150, + ["brass helmet"] = 30, + ["brass legs"] = 49, + ["brass shield"] = 25, + ["bright bell"] = 220, + ["bright sword"] = 6000, + ["brimstone fangs"] = 380, + ["brimstone shell"] = 210, + ["broadsword"] = 500, + ["broken crossbow"] = 30, + ["broken draken mail"] = 340, + ["broken gladiator shield"] = 190, + ["broken halberd"] = 100, + ["broken helmet"] = 20, + ["broken key ring"] = 8000, + ["broken longbow"] = 120, + ["broken ring of ending"] = 4000, + ["broken shamanic staff"] = 35, + ["broken slicer"] = 120, + ["broken throwing axe"] = 230, + ["broken visor"] = 1900, + ["bronze amulet"] = 50, + ["brooch of embracement"] = 14000, + ["brown crystal splinter"] = 400, + ["brown piece of cloth"] = 100, + ["brutetamer's staff"] = 1500, + ["buckle"] = 7000, + ["bullseye potion"] = 500, + ["bunch of ripe rice"] = 75, + ["bunch of troll hair"] = 30, + ["bundle of cursed straw"] = 800, + ["butcher's axe"] = 18000, + ["calopteryx cape"] = 15000, + ["capricious heart"] = 2100, + ["capricious robe"] = 1200, + ["carapace shield"] = 32000, + ["carlin sword"] = 118, + ["carniphila seeds"] = 50, + ["carrion worm fang"] = 35, + ["castle shield"] = 5000, + ["cat's paw"] = 2000, + ["cave devourer eyes"] = 550, + ["cave devourer legs"] = 350, + ["cave devourer maw"] = 600, + ["cavebear skull"] = 550, + ["centipede leg"] = 28, + ["ceremonial ankh"] = 20000, + ["chain armor"] = 70, + ["chain bolter"] = 40000, + ["chain helmet"] = 17, + ["chain legs"] = 25, + ["chaos mace"] = 9000, + ["charmer's tiara"] = 900, + ["chasm spawn abdomen"] = 240, + ["chasm spawn head"] = 850, + ["chasm spawn tail"] = 120, + ["cheese cutter"] = 50, + ["cheesy figurine"] = 150, + ["chicken feather"] = 30, + ["chitinous mouth"] = 10000, + ["claw of 'the noxious spawn'"] = 15000, + ["cliff strider claw"] = 800, + ["closed trap"] = 75, + ["club"] = 1, + ["club ring"] = 100, + ["coal"] = 20, + ["coat"] = 1, + ["cobra crest"] = 650, + ["cobra crown"] = 50000, + ["cobra tongue"] = 15, + ["coconut shoes"] = 500, + ["collar of blue plasma"] = 6000, + ["collar of green plasma"] = 6000, + ["collar of red plasma"] = 6000, + ["colourful feather"] = 110, + ["colourful feathers"] = 400, + ["colourful snail shell"] = 250, + ["compass"] = 45, + ["composite hornbow"] = 25000, + ["compound eye"] = 150, + ["condensed energy"] = 260, + ["copper shield"] = 50, + ["coral brooch"] = 750, + ["corrupted flag"] = 700, + ["countess sorrow's frozen tear"] = 50000, + ["cow bell"] = 120, + ["cowtana"] = 2500, + ["crab pincers"] = 35, + ["cracked alabaster vase"] = 180, + ["cranial basher"] = 30000, + ["crawler head plating"] = 210, + ["crawler's essence"] = 3700, + ["crest of the deep seas"] = 10000, + ["crocodile boots"] = 1000, + ["crossbow"] = 120, + ["crowbar"] = 50, + ["crown"] = 2700, + ["crown armor"] = 12000, + ["crown helmet"] = 2500, + ["crown legs"] = 12000, + ["crown shield"] = 8000, + ["cruelty's chest"] = 720000, + ["cruelty's claw"] = 640000, + ["crunor idol"] = 30000, + ["crusader helmet"] = 6000, + ["crystal bone"] = 250, + ["crystal crossbow"] = 35000, + ["crystal mace"] = 12000, + ["crystal necklace"] = 400, + ["crystal of balance"] = 1000, + ["crystal of focus"] = 2000, + ["crystal of power"] = 3000, + ["crystal pedestal"] = 500, + ["crystal ring"] = 250, + ["crystal sword"] = 600, + ["crystal wand"] = 10000, + ["crystalline armor"] = 16000, + ["crystalline spikes"] = 440, + ["crystallized anger"] = 400, + ["cultish mask"] = 280, + ["cultish robe"] = 150, + ["cultish symbol"] = 500, + ["curious matter"] = 430, + ["cursed bone"] = 6000, + ["cursed shoulder spikes"] = 320, + ["cyan crystal fragment"] = 800, + ["cyclops toe"] = 55, + ["cyclops trophy"] = 500, + ["dagger"] = 2, + ["damaged armor plates"] = 280, + ["damaged worm head"] = 8000, + ["damselfly eye"] = 25, + ["damselfly wing"] = 20, + ["dandelion seeds"] = 200, + ["dangerous proto matter"] = 300, + ["daramian mace"] = 110, + ["daramian waraxe"] = 1000, + ["dark armor"] = 400, + ["dark bell"] = 250, + ["dark helmet"] = 250, + ["dark mushroom"] = 100, + ["dark rosary"] = 48, + ["dark shield"] = 400, + ["dead rat"] = 1, + ["dead weight"] = 450, + ["death ring"] = 1000, + ["deepling axe"] = 40000, + ["deepling breaktime snack"] = 90, + ["deepling claw"] = 430, + ["deepling guard belt buckle"] = 230, + ["deepling ridge"] = 360, + ["deepling scales"] = 80, + ["deepling squelcher"] = 7000, + ["deepling staff"] = 4000, + ["deepling warts"] = 180, + ["deeptags"] = 290, + ["deepworm jaws"] = 500, + ["deepworm spike roots"] = 650, + ["deepworm spikes"] = 800, + ["deer trophy3"] = 3000, + ["demon dust"] = 300, + ["demon helmet"] = 40000, + ["demon horn"] = 1000, + ["demon shield"] = 30000, + ["demon trophy"] = 40000, + ["demonbone amulet"] = 32000, + ["demonic essence"] = 1000, + ["demonic finger"] = 1000, + ["demonic skeletal hand"] = 80, + ["demonrage sword"] = 36000, + ["depth calcei"] = 25000, + ["depth galea"] = 35000, + ["depth lorica"] = 30000, + ["depth ocrea"] = 16000, + ["depth scutum"] = 36000, + ["devil helmet"] = 1000, + ["diabolic skull"] = 19000, + ["diamond"] = 15000, + ["diamond sceptre"] = 3000, + ["diremaw brainpan"] = 350, + ["diremaw legs"] = 270, + ["dirty turban"] = 120, + ["disgusting trophy"] = 3000, + ["distorted heart"] = 2100, + ["distorted robe"] = 1200, + ["divine plate"] = 55000, + ["djinn blade"] = 15000, + ["doll"] = 200, + ["double axe"] = 260, + ["doublet"] = 3, + ["downy feather"] = 20, + ["dowser"] = 35, + ["drachaku"] = 10000, + ["dracola's eye"] = 50000, + ["dracoyle statue"] = 5000, + ["dragon blood"] = 700, + ["dragon claw"] = 8000, + ["dragon figurine"] = 45000, + ["dragon hammer"] = 2000, + ["dragon lance"] = 9000, + ["dragon lord trophy"] = 10000, + ["dragon necklace"] = 100, + ["dragon priest's wandtip"] = 175, + ["dragon robe"] = 50000, + ["dragon scale mail"] = 40000, + ["dragon shield"] = 4000, + ["dragon slayer"] = 15000, + ["dragon tongue"] = 550, + ["dragonbone staff"] = 3000, + ["dragon's tail"] = 100, + ["draken boots"] = 40000, + ["draken sulphur"] = 550, + ["draken trophy"] = 15000, + ["draken wristbands"] = 430, + ["drakinata"] = 10000, + ["draptor scales"] = 800, + ["dreaded cleaver"] = 10000, + ["dream essence egg"] = 205, + ["dung ball"] = 130, + ["dwarven armor"] = 30000, + ["dwarven axe"] = 1500, + ["dwarven legs"] = 40000, + ["dwarven ring"] = 100, + ["dwarven shield"] = 100, + ["earflap"] = 40, + ["earth blacksteel sword"] = 6000, + ["earth cranial basher"] = 30000, + ["earth crystal mace"] = 12000, + ["earth dragon slayer"] = 15000, + ["earth headchopper"] = 6000, + ["earth heroic axe"] = 30000, + ["earth knight axe"] = 2000, + ["earth mystic blade"] = 30000, + ["earth orcish maul"] = 6000, + ["earth relic sword"] = 25000, + ["earth spike sword"] = 1000, + ["earth war axe"] = 12000, + ["earth war hammer"] = 1200, + ["ectoplasmic sushi"] = 300, + ["egg of the many"] = 15000, + ["elder bonelord tentacle"] = 150, + ["elite draken mail"] = 50000, + ["elven amulet"] = 100, + ["elven astral observer"] = 90, + ["elven hoof"] = 115, + ["elven scouting glass"] = 50, + ["elvish bow"] = 2000, + ["elvish talisman"] = 45, + ["emerald bangle"] = 800, + ["empty honey glass"] = 270, + ["empty potion flask"] = 5, + ["enchanted chicken wing"] = 20000, + ["energy ball"] = 300, + ["energy blacksteel sword"] = 6000, + ["energy cranial basher"] = 30000, + ["energy crystal mace"] = 12000, + ["energy dragon slayer"] = 15000, + ["energy headchopper"] = 6000, + ["energy heroic axe"] = 30000, + ["energy knight axe"] = 2000, + ["energy mystic blade"] = 30000, + ["energy orcish maul"] = 6000, + ["energy relic sword"] = 25000, + ["energy ring"] = 100, + ["energy spike sword"] = 1000, + ["energy vein"] = 270, + ["energy war axe"] = 12000, + ["energy war hammer"] = 1200, + ["ensouled essence"] = 820, + ["epee"] = 8000, + ["essence of a bad dream"] = 360, + ["ethno coat"] = 200, + ["execowtioner axe"] = 12000, + ["executioner"] = 55000, + ["explorer brooch"] = 50, + ["eye of a deepling"] = 150, + ["eye of a weeper"] = 650, + ["eye of corruption"] = 390, + ["fafnar symbol"] = 950, + ["fairy wings"] = 200, + ["falcon crest"] = 650, + ["feather headdress"] = 850, + ["fern"] = 20, + ["fiery blacksteel sword"] = 6000, + ["fiery cranial basher"] = 30000, + ["fiery crystal mace"] = 12000, + ["fiery dragon slayer"] = 15000, + ["fiery headchopper"] = 6000, + ["fiery heart"] = 375, + ["fiery heroic axe"] = 30000, + ["fiery knight axe"] = 2000, + ["fiery mystic blade"] = 30000, + ["fiery orcish maul"] = 6000, + ["fiery relic sword"] = 25000, + ["fiery spike sword"] = 1000, + ["fiery war axe"] = 12000, + ["fiery war hammer"] = 1200, + ["fig leaf"] = 200, + ["figurine of cruelty"] = 3100000, + ["figurine of greed"] = 2900000, + ["figurine of hatred"] = 2700000, + ["figurine of malice"] = 2800000, + ["figurine of megalomania"] = 5000000, + ["figurine of spite"] = 3000000, + ["fir cone"] = 25, + ["fire axe"] = 8000, + ["fire mushroom"] = 200, + ["fire sword"] = 1000, + ["fish fin"] = 150, + ["fishing rod"] = 40, + ["flask of embalming fluid"] = 30, + ["flask of warrior's sweat"] = 10000, + ["flintstone"] = 800, + ["flower dress"] = 1000, + ["flower wreath"] = 500, + ["focus cape"] = 6000, + ["fox paw"] = 100, + ["frazzle skin"] = 400, + ["frazzle tongue"] = 700, + ["frost giant pelt"] = 160, + ["frosty ear of a troll"] = 30, + ["frosty heart"] = 280, + ["frozen lightning"] = 270, + ["frozen starlight"] = 20000, + ["fur armor"] = 5000, + ["fur boots"] = 2000, + ["fur shred"] = 200, + ["furry club"] = 1000, + ["garlic necklace"] = 50, + ["gauze bandage"] = 90, + ["gear crystal"] = 200, + ["gear wheel"] = 500, + ["gearwheel chain"] = 5000, + ["gemmed figurine"] = 3500, + ["geomancer's robe"] = 80, + ["geomancer's staff"] = 120, + ["ghastly dragon head"] = 700, + ["ghostly tissue"] = 90, + ["ghoul snack"] = 60, + ["giant amethyst"] = 60000, + ["giant crab pincer"] = 950, + ["giant emerald"] = 90000, + ["giant eye"] = 380, + ["giant ruby"] = 70000, + ["giant sapphire"] = 50000, + ["giant shimmering pearl"] = 3000, + ["giant smithhammer"] = 250, + ["giant sword"] = 17000, + ["giant tentacle"] = 10000, + ["giant topaz"] = 80000, + ["girlish hair decoration"] = 30, + ["glacial rod"] = 6500, + ["glacier amulet"] = 1500, + ["glacier kilt"] = 11000, + ["glacier mask"] = 2500, + ["glacier robe"] = 11000, + ["glacier shoes"] = 2500, + ["gland"] = 500, + ["glistening bone"] = 250, + ["glob of acid slime"] = 25, + ["glob of mercury"] = 20, + ["glob of tar"] = 30, + ["gloom wolf fur"] = 70, + ["glooth amulet"] = 2000, + ["glooth axe"] = 1500, + ["glooth blade"] = 1500, + ["glooth cape"] = 7000, + ["glooth club"] = 1500, + ["glooth whip"] = 2500, + ["glorious axe"] = 3000, + ["glowing rune"] = 350, + ["goanna claw"] = 260, + ["goanna meat"] = 190, + ["goat grass"] = 50, + ["goblet of gloom"] = 12000, + ["goblin ear"] = 20, + ["gold ingot"] = 5000, + ["gold nugget"] = 850, + ["gold ring"] = 8000, + ["golden amulet"] = 2000, + ["golden armor"] = 20000, + ["golden brush"] = 250, + ["golden fafnar trophy"] = 10000, + ["golden figurine"] = 3000, + ["golden legs"] = 30000, + ["golden lotus brooch"] = 270, + ["golden mask"] = 38000, + ["golden mug"] = 250, + ["golden sickle"] = 1000, + ["goo shell"] = 4000, + ["goosebump leather"] = 650, + ["grant of arms"] = 950, + ["grasshopper legs"] = 15000, + ["grave flower"] = 25, + ["greed's arm"] = 950000, + ["green bandage"] = 180, + ["green crystal fragment"] = 800, + ["green crystal shard"] = 1500, + ["green crystal splinter"] = 400, + ["green dragon leather"] = 100, + ["green dragon scale"] = 100, + ["green gem"] = 5000, + ["green glass plate"] = 180, + ["green mushroom"] = 100, + ["green piece of cloth"] = 200, + ["greenwood coat"] = 50000, + ["griffin shield"] = 3000, + ["grimace"] = 120000, + ["gruesome fan"] = 15000, + ["guardian axe"] = 9000, + ["guardian boots"] = 35000, + ["guardian halberd"] = 11000, + ["guardian shield"] = 2000, + ["guidebook"] = 200, + ["hailstorm rod"] = 3000, + ["hair of a banshee"] = 350, + ["halberd"] = 400, + ["half-digested piece of meat"] = 55, + ["half-digested stones"] = 40, + ["half-eaten brain"] = 85, + ["ham"] = 4, + ["hammer of wrath"] = 30000, + ["hand"] = 1450, + ["hand axe"] = 4, + ["hardened bone"] = 70, + ["harpoon of a giant snail"] = 15000, + ["hatched rorc egg"] = 30, + ["hatchet"] = 25, + ["haunted blade"] = 8000, + ["haunted piece of wood"] = 115, + ["hazardous heart"] = 5000, + ["hazardous robe"] = 3000, + ["head"] = 3500, + ["headchopper"] = 6000, + ["heat core"] = 10000, + ["heaven blossom"] = 50, + ["heavy mace"] = 50000, + ["heavy machete"] = 90, + ["heavy trident"] = 2000, + ["hellhound slobber"] = 500, + ["hellspawn tail"] = 475, + ["helmet of the lost"] = 2000, + ["hemp rope"] = 350, + ["heroic axe"] = 30000, + ["hexagonal ruby"] = 30000, + ["hibiscus dress"] = 3000, + ["hideous chunk"] = 510, + ["hieroglyph banner"] = 500, + ["high guard flag"] = 550, + ["high guard shoulderplates"] = 130, + ["hive bow"] = 28000, + ["hive scythe"] = 17000, + ["hollow stampor hoof"] = 400, + ["holy ash"] = 160, + ["holy orchid"] = 90, + ["honeycomb"] = 40, + ["horn"] = 300, + ["horn of kalyassa"] = 10000, + ["horoscope"] = 40, + ["horseman helmet"] = 280, + ["huge chunk of crude iron"] = 15000, + ["huge shell"] = 15000, + ["huge spiky snail shell"] = 8000, + ["humongous chunk"] = 540, + ["hunter's quiver"] = 80, + ["hunting spear"] = 25, + ["hydra egg"] = 500, + ["hydra head"] = 600, + ["ice flower"] = 370, + ["ice rapier"] = 1000, + ["icy blacksteel sword"] = 6000, + ["icy cranial basher"] = 30000, + ["icy crystal mace"] = 12000, + ["icy dragon slayer"] = 15000, + ["icy headchopper"] = 6000, + ["icy heroic axe"] = 30000, + ["icy knight axe"] = 2000, + ["icy mystic blade"] = 30000, + ["icy orcish maul"] = 6000, + ["icy relic sword"] = 25000, + ["icy spike sword"] = 1000, + ["icy war axe"] = 12000, + ["icy war hammer"] = 1200, + ["incantation notes"] = 90, + ["infernal heart"] = 2100, + ["infernal robe"] = 1200, + ["inkwell"] = 8, + ["instable proto matter"] = 300, + ["iron helmet"] = 150, + ["iron ore"] = 500, + ["ivory carving"] = 300, + ["ivory comb"] = 8000, + ["izcandar's snow globe"] = 180000, + ["izcandar's sundial"] = 225000, + ["jacket"] = 1, + ["jade hammer"] = 25000, + ["jade hat"] = 9000, + ["jagged sickle"] = 150000, + ["jaws"] = 3900, + ["jewelled belt"] = 180, + ["katana"] = 35, + ["katex' blood"] = 210, + ["key to the drowned library"] = 330, + ["knight armor"] = 5000, + ["knight axe"] = 2000, + ["knight legs"] = 5000, + ["kollos shell"] = 420, + ["kongra's shoulderpad"] = 100, + ["krimhorn helmet"] = 200, + ["lamassu hoof"] = 330, + ["lamassu horn"] = 240, + ["lancer beetle shell"] = 80, + ["lancet"] = 90, + ["lavos armor"] = 16000, + ["leaf legs"] = 500, + ["leather armor"] = 12, + ["leather boots"] = 2, + ["leather harness"] = 750, + ["leather helmet"] = 4, + ["leather legs"] = 9, + ["legion helmet"] = 22, + ["legionnaire flags"] = 500, + ["leopard armor"] = 300, + ["leviathan's amulet"] = 3000, + ["life crystal"] = 50, + ["life preserver"] = 300, + ["life ring"] = 50, + ["light shovel"] = 300, + ["lightning boots"] = 2500, + ["lightning headband"] = 2500, + ["lightning legs"] = 11000, + ["lightning pendant"] = 1500, + ["lightning robe"] = 11000, + ["lion cloak patch"] = 190, + ["lion crest"] = 270, + ["lion figurine"] = 10000, + ["lion seal"] = 210, + ["lion trophy3"] = 3000, + ["lion's mane"] = 60, + ["little bowl of myrrh"] = 500, + ["lizard essence"] = 300, + ["lizard heart"] = 530, + ["lizard leather"] = 150, + ["lizard scale"] = 120, + ["lizard trophy"] = 8000, + ["longing eyes"] = 8000, + ["longsword"] = 51, + ["lost basher's spike"] = 280, + ["lost bracers"] = 140, + ["lost husher's staff"] = 250, + ["lost soul"] = 120, + ["luminescent crystal pickaxe"] = 50, + ["luminous orb"] = 1000, + ["lump of dirt"] = 10, + ["lump of earth"] = 130, + ["lunar staff"] = 5000, + ["mace"] = 30, + ["machete"] = 6, + ["mad froth"] = 80, + ["magic light wand"] = 35, + ["magic plate armor"] = 90000, + ["magic sulphur"] = 8000, + ["magma amulet"] = 1500, + ["magma boots"] = 2500, + ["magma clump"] = 570, + ["magma coat"] = 11000, + ["magma legs"] = 11000, + ["magma monocle"] = 2500, + ["malice's horn"] = 620000, + ["malice's spine"] = 850000, + ["malofur's lunchbox"] = 240000, + ["mammoth fur cape"] = 6000, + ["mammoth fur shorts"] = 850, + ["mammoth tusk"] = 100, + ["mammoth whopper"] = 300, + ["mantassin tail"] = 280, + ["manticore ear"] = 310, + ["manticore tail"] = 220, + ["marlin trophy"] = 5000, + ["marsh stalker beak"] = 65, + ["marsh stalker feather"] = 50, + ["mastermind potion"] = 500, + ["mastermind shield"] = 50000, + ["maxilla"] = 250, + ["maxxenius head"] = 500000, + ["meat"] = 2, + ["meat hammer"] = 60, + ["medal of valiance"] = 410000, + ["medusa shield"] = 9000, + ["megalomania's essence"] = 1900000, + ["megalomania's skull"] = 1500000, + ["mercenary sword"] = 12000, + ["metal bat"] = 9000, + ["metal spats"] = 2000, + ["metal spike"] = 320, + ["might ring"] = 250, + ["milk churn"] = 100, + ["mind stone"] = 100, + ["mino lance"] = 7000, + ["mino shield"] = 3000, + ["minotaur horn"] = 75, + ["minotaur leather"] = 80, + ["minotaur trophy"] = 500, + ["miraculum"] = 60, + ["mirror"] = 10, + ["model ship"] = 1000, + ["modified crossbow"] = 10000, + ["mooh'tah plate"] = 6000, + ["moohtant cudgel"] = 14000, + ["moonlight rod"] = 200, + ["moonstone"] = 13000, + ["morbid tapestry"] = 30000, + ["morgaroth's heart"] = 15000, + ["morning star"] = 100, + ["mould heart"] = 2100, + ["mould robe"] = 1200, + ["mr. punish's handcuffs"] = 50000, + ["muck rod"] = 6000, + ["mucus plug"] = 500, + ["mutated bat ear"] = 420, + ["mutated flesh"] = 50, + ["mutated rat tail"] = 150, + ["mycological bow"] = 35000, + ["mysterious fetish"] = 50, + ["mystic blade"] = 30000, + ["mystic turban"] = 150, + ["mystical hourglass"] = 700, + ["naginata"] = 2000, + ["necklace of the deep"] = 3000, + ["necromantic robe"] = 250, + ["necrotic rod"] = 1000, + ["nettle blossom"] = 75, + ["nettle spit"] = 25, + ["nightmare blade"] = 35000, + ["noble amulet"] = 430000, + ["noble armor"] = 900, + ["noble axe"] = 10000, + ["noble cape"] = 425000, + ["noble turban"] = 430, + ["norse shield"] = 1500, + ["northwind rod"] = 1500, + ["nose ring"] = 2000, + ["obsidian lance"] = 500, + ["odd organ"] = 410, + ["ogre ear stud"] = 180, + ["ogre nose ring"] = 210, + ["old parchment"] = 500, + ["onyx chip"] = 500, + ["onyx flail"] = 22000, + ["onyx pendant"] = 3500, + ["opal"] = 500, + ["orange mushroom"] = 150, + ["orb"] = 750, + ["orc leather"] = 30, + ["orc tooth"] = 150, + ["orc trophy3"] = 1000, + ["orcish axe"] = 350, + ["orcish gear"] = 85, + ["orcish maul"] = 6000, + ["orichalcum pearl"] = 40, + ["oriental shoes"] = 15000, + ["ornamented axe"] = 20000, + ["ornamented shield"] = 1500, + ["ornate chestplate"] = 60000, + ["ornate crossbow"] = 12000, + ["ornate legs"] = 40000, + ["ornate locket"] = 18000, + ["ornate mace"] = 42000, + ["ornate shield"] = 42000, + ["orshabaal's brain"] = 12000, + ["pair of hellflayer horns"] = 1300, + ["pair of iron fists"] = 4000, + ["pair of old bracers"] = 500, + ["paladin armor"] = 15000, + ["pale worm's scalp"] = 489000, + ["panda teddy"] = 30000, + ["panther head"] = 750, + ["panther paw"] = 300, + ["patch of fine cloth"] = 1350, + ["patched boots"] = 2000, + ["peacock feather fan"] = 350, + ["pelvis bone"] = 30, + ["perfect behemoth fang"] = 250, + ["pet pig"] = 1500, + ["petrified scream"] = 250, + ["phantasmal hair"] = 500, + ["pharaoh banner"] = 1000, + ["pharaoh sword"] = 23000, + ["phoenix shield"] = 16000, + ["pick"] = 15, + ["piece of archer armor"] = 20, + ["piece of crocodile leather"] = 15, + ["piece of dead brain"] = 420, + ["piece of draconian steel"] = 3000, + ["piece of hell steel"] = 500, + ["piece of hellfire armor"] = 550, + ["piece of massacre's shell"] = 50000, + ["piece of royal steel"] = 10000, + ["piece of scarab shell"] = 45, + ["piece of swampling wood"] = 30, + ["piece of warrior armor"] = 50, + ["pieces of magic chalk"] = 210, + ["pig foot"] = 10, + ["pile of grave earth"] = 25, + ["pirate boots"] = 3000, + ["pirate hat"] = 1000, + ["pirate knee breeches"] = 200, + ["pirate shirt"] = 500, + ["pirate voodoo doll"] = 500, + ["plagueroot offshoot"] = 280000, + ["plasma pearls"] = 250, + ["plasmatic lightning"] = 270, + ["plate armor"] = 400, + ["plate legs"] = 115, + ["plate shield"] = 45, + ["platinum amulet"] = 2500, + ["poison dagger"] = 50, + ["poison gland"] = 210, + ["poison spider shell"] = 10, + ["poisonous slime"] = 50, + ["polar bear paw"] = 30, + ["pool of chitinous glue"] = 480, + ["porcelain mask"] = 2000, + ["powder herb"] = 10, + ["power ring"] = 50, + ["prismatic quartz"] = 450, + ["pristine worm head"] = 15000, + ["protection amulet"] = 100, + ["protective charm"] = 60, + ["pulverized ore"] = 400, + ["purified soul"] = 530, + ["purple robe"] = 110, + ["purple tome"] = 2000, + ["quara bone"] = 500, + ["quara eye"] = 350, + ["quara pincers"] = 410, + ["quara tentacle"] = 140, + ["queen's sceptre"] = 20000, + ["quill"] = 1100, + ["rabbit's foot"] = 50, + ["ragnir helmet"] = 400, + ["rainbow quartz"] = 500, + ["rapier"] = 5, + ["rare earth"] = 80, + ["ratana"] = 500, + ["ravenous circlet"] = 220000, + ["red crystal fragment"] = 800, + ["red dragon leather"] = 200, + ["red dragon scale"] = 200, + ["red gem"] = 1000, + ["red goanna scale"] = 270, + ["red hair dye"] = 40, + ["red lantern"] = 250, + ["red piece of cloth"] = 300, + ["red tome"] = 2000, + ["relic sword"] = 25000, + ["rhino hide"] = 175, + ["rhino horn"] = 265, + ["rhino horn carving"] = 300, + ["rift bow"] = 45000, + ["rift crossbow"] = 45000, + ["rift lance"] = 30000, + ["rift shield"] = 50000, + ["ring of blue plasma"] = 8000, + ["ring of green plasma"] = 8000, + ["ring of healing"] = 100, + ["ring of red plasma"] = 8000, + ["ring of the sky"] = 30000, + ["ripper lance"] = 500, + ["rod"] = 2200, + ["roots"] = 1200, + ["rope"] = 15, + ["rope belt"] = 66, + ["rorc egg"] = 120, + ["rorc feather"] = 70, + ["rotten heart"] = 74000, + ["rotten piece of cloth"] = 30, + ["royal axe"] = 40000, + ["royal helmet"] = 30000, + ["royal tapestry"] = 1000, + ["rubber cap"] = 11000, + ["ruby necklace"] = 2000, + ["runed sword"] = 45000, + ["ruthless axe"] = 45000, + ["sabre"] = 12, + ["sabretooth"] = 400, + ["sacred tree amulet"] = 3000, + ["safety pin"] = 120, + ["sai"] = 16500, + ["salamander shield"] = 280, + ["sample of monster blood"] = 250, + ["sandcrawler shell"] = 20, + ["sapphire hammer"] = 7000, + ["scale armor"] = 75, + ["scale of corruption"] = 680, + ["scale of gelidrazah"] = 10000, + ["scarab amulet"] = 200, + ["scarab pincers"] = 280, + ["scarab shield"] = 2000, + ["scimitar"] = 150, + ["scorpion tail"] = 25, + ["scroll of heroic deeds"] = 230, + ["scythe"] = 10, + ["scythe leg"] = 450, + ["sea horse figurine"] = 42000, + ["sea serpent scale"] = 520, + ["sea serpent trophy"] = 10000, + ["seeds"] = 150, + ["sentinel shield"] = 120, + ["serpent sword"] = 900, + ["shadow herb"] = 20, + ["shadow sceptre"] = 10000, + ["shaggy tail"] = 25, + ["shamanic hood"] = 45, + ["shamanic talisman"] = 200, + ["shard"] = 2000, + ["shimmering beetles"] = 150, + ["shiny stone"] = 500, + ["shockwave amulet"] = 3000, + ["short sword"] = 10, + ["shovel"] = 8, + ["sickle"] = 3, + ["sight of surrender's eye"] = 3000, + ["signet ring"] = 480000, + ["silencer claws"] = 390, + ["silencer resonating chamber"] = 600, + ["silken bookmark"] = 1300, + ["silkweaver bow"] = 12000, + ["silky fur"] = 35, + ["silver amulet"] = 50, + ["silver brooch"] = 150, + ["silver dagger"] = 500, + ["silver fafnar trophy"] = 1000, + ["silver hand mirror"] = 10000, + ["simple dress"] = 50, + ["single human eye"] = 1000, + ["skeleton decoration"] = 3000, + ["skull belt"] = 80, + ["skull coin"] = 12000, + ["skull fetish"] = 250, + ["skull helmet"] = 40000, + ["skull of ratha"] = 250, + ["skull shatterer"] = 170, + ["skull staff"] = 6000, + ["skullcracker armor"] = 18000, + ["skunk tail"] = 50, + ["slime mould"] = 175, + ["slimy leg"] = 4500, + ["sling herb"] = 10, + ["small amethyst"] = 200, + ["small axe"] = 5, + ["small diamond"] = 300, + ["small emerald"] = 250, + ["small enchanted amethyst"] = 200, + ["small enchanted emerald"] = 250, + ["small enchanted ruby"] = 250, + ["small enchanted sapphire"] = 250, + ["small energy ball"] = 250, + ["small flask of eyedrops"] = 95, + ["small notebook"] = 480, + ["small oil lamp"] = 150, + ["small pitchfork"] = 70, + ["small ruby"] = 250, + ["small sapphire"] = 250, + ["small topaz"] = 200, + ["snake skin"] = 400, + ["snakebite rod"] = 100, + ["sniper gloves"] = 2000, + ["soldier helmet"] = 16, + ["solid rage"] = 310, + ["some grimeleech wings"] = 1200, + ["soul orb"] = 25, + ["soul stone"] = 6000, + ["souleater trophy"] = 7500, + ["spark sphere"] = 350, + ["sparkion claw"] = 290, + ["sparkion legs"] = 310, + ["sparkion stings"] = 280, + ["sparkion tail"] = 300, + ["spear"] = 3, + ["spectral gold nugget"] = 500, + ["spectral silver nugget"] = 250, + ["spellsinger's seal"] = 280, + ["spellweaver's robe"] = 12000, + ["sphinx feather"] = 470, + ["sphinx tiara"] = 360, + ["spider fangs"] = 10, + ["spider silk"] = 100, + ["spidris mandible"] = 450, + ["spike shield"] = 250, + ["spike sword"] = 240, + ["spiked iron ball"] = 100, + ["spiked squelcher"] = 5000, + ["spiky club"] = 300, + ["spirit cloak"] = 350, + ["spirit container"] = 40000, + ["spite's spirit"] = 840000, + ["spitter nose"] = 340, + ["spooky blue eye"] = 95, + ["spool of yarn"] = 1000, + ["springsprout rod"] = 3600, + ["srezz' eye"] = 300, + ["stampor horn"] = 280, + ["stampor talons"] = 150, + ["star amulet"] = 500, + ["star herb"] = 15, + ["statue of abyssador"] = 4000, + ["statue of deathstrike"] = 3000, + ["statue of devovorga"] = 1500, + ["statue of gnomevil"] = 2000, + ["stealth ring"] = 200, + ["steel boots"] = 30000, + ["steel helmet"] = 293, + ["steel shield"] = 80, + ["stone herb"] = 20, + ["stone nose"] = 590, + ["stone skin amulet"] = 500, + ["stone wing"] = 120, + ["stonerefiner's skull"] = 100, + ["strand of medusa hair"] = 600, + ["strange helmet"] = 500, + ["strange proto matter"] = 300, + ["strange symbol"] = 200, + ["strange talisman"] = 30, + ["striped fur"] = 50, + ["studded armor"] = 25, + ["studded club"] = 10, + ["studded helmet"] = 20, + ["studded legs"] = 15, + ["studded shield"] = 16, + ["stuffed dragon"] = 6000, + ["sulphurous stone"] = 100, + ["swamp grass"] = 20, + ["swamplair armor"] = 16000, + ["swampling club"] = 40, + ["swampling moss"] = 20, + ["swarmer antenna"] = 130, + ["sword"] = 25, + ["sword ring"] = 100, + ["tail of corruption"] = 240, + ["talon"] = 320, + ["tarantula egg"] = 80, + ["tarnished rhino figurine"] = 320, + ["tattered piece of robe"] = 120, + ["taurus mace"] = 500, + ["telescope eye"] = 1600, + ["tempest shield"] = 35000, + ["templar scytheblade"] = 200, + ["tentacle piece"] = 5000, + ["terra amulet"] = 1500, + ["terra boots"] = 2500, + ["terra hood"] = 2500, + ["terra legs"] = 11000, + ["terra mantle"] = 11000, + ["terra rod"] = 2000, + ["terramite eggs"] = 50, + ["terramite legs"] = 60, + ["terramite shell"] = 170, + ["terrorbird beak"] = 95, + ["thaian sword"] = 16000, + ["the avenger"] = 42000, + ["the handmaiden's protector"] = 50000, + ["the imperor's trident"] = 50000, + ["the ironworker"] = 50000, + ["the justice seeker"] = 40000, + ["the plasmother's remains"] = 50000, + ["thick fur"] = 150, + ["thorn"] = 100, + ["throwing knife"] = 2, + ["tiger eye"] = 350, + ["time ring"] = 100, + ["titan axe"] = 4000, + ["token of love"] = 440000, + ["tooth file"] = 60, + ["tooth of tazhadur"] = 10000, + ["torn shirt"] = 250, + ["tortoise shield"] = 150, + ["tower shield"] = 8000, + ["trapped bad dream monster"] = 900, + ["trashed draken boots"] = 40000, + ["tribal mask"] = 250, + ["troll green"] = 25, + ["trollroot"] = 50, + ["trophy of jaul"] = 4000, + ["trophy of obujos"] = 3000, + ["trophy of tanjis"] = 2000, + ["tunnel tyrant head"] = 500, + ["tunnel tyrant shell"] = 700, + ["turtle shell"] = 90, + ["tusk"] = 100, + ["tusk shield"] = 850, + ["twiceslicer"] = 28000, + ["twin hooks"] = 500, + ["two handed sword"] = 450, + ["undead heart"] = 200, + ["underworld rod"] = 4400, + ["unholy bone"] = 480, + ["unholy book"] = 30000, + ["unicorn figurine"] = 50000, + ["urmahlullu's mane"] = 490000, + ["urmahlullu's paw"] = 245000, + ["urmahlullu's tail"] = 210000, + ["utua's poison"] = 230, + ["vampire dust"] = 100, + ["vampire shield"] = 15000, + ["vampire teeth"] = 275, + ["vampire's cape chain"] = 150, + ["veal"] = 40, + ["vein of ore"] = 330, + ["velvet tapestry"] = 800, + ["venison"] = 55, + ["vexclaw talon"] = 1100, + ["vial"] = 5, + ["vial of hatred"] = 737000, + ["vibrant heart"] = 2100, + ["vibrant robe"] = 1200, + ["viking helmet"] = 66, + ["viking shield"] = 85, + ["vile axe"] = 30000, + ["violet crystal shard"] = 1500, + ["violet gem"] = 10000, + ["violet glass plate"] = 2150, + ["volatile proto matter"] = 300, + ["voodoo doll"] = 400, + ["wailing widow's necklace"] = 3000, + ["walnut"] = 80, + ["wand of cosmic energy"] = 2000, + ["wand of decay"] = 1000, + ["wand of defiance"] = 6500, + ["wand of draconia"] = 1500, + ["wand of dragonbreath"] = 200, + ["wand of everblazing"] = 6000, + ["wand of inferno"] = 3000, + ["wand of starstorm"] = 3600, + ["wand of voodoo"] = 4400, + ["wand of vortex"] = 100, + ["war axe"] = 12000, + ["war crystal"] = 460, + ["war hammer"] = 470, + ["war horn"] = 8000, + ["warmaster's wristguards"] = 200, + ["warrior helmet"] = 5000, + ["warrior's axe"] = 11000, + ["warrior's shield"] = 9000, + ["warwolf fur"] = 30, + ["waspoid claw"] = 320, + ["waspoid wing"] = 190, + ["watch"] = 6, + ["watermelon tourmaline"] = 30000, + ["weaver's wandtip"] = 250, + ["wedding ring"] = 100, + ["werebadger claws"] = 160, + ["werebadger skull"] = 185, + ["werebadger trophy"] = 9000, + ["werebear fur"] = 185, + ["werebear skull"] = 195, + ["werebear trophy"] = 11000, + ["wereboar hooves"] = 175, + ["wereboar loincloth"] = 1500, + ["wereboar trophy"] = 10000, + ["wereboar tusks"] = 165, + ["werefox tail"] = 200, + ["werefox trophy"] = 9000, + ["werehyaena nose"] = 220, + ["werehyaena talisman"] = 350, + ["werehyaena trophy"] = 12000, + ["werewolf amulet"] = 3000, + ["werewolf fangs"] = 180, + ["werewolf fur"] = 380, + ["white deer antlers"] = 400, + ["white deer skin"] = 245, + ["white gem"] = 12000, + ["white pearl"] = 160, + ["white piece of cloth"] = 100, + ["white silk flower"] = 9000, + ["widow's mandibles"] = 110, + ["wild flowers"] = 120, + ["wimp tooth chain"] = 120, + ["windborn colossus armor"] = 50000, + ["winged tail"] = 800, + ["winter wolf fur"] = 20, + ["witch broom"] = 60, + ["witch hat"] = 5000, + ["withered pauldrons"] = 850, + ["withered scalp"] = 900, + ["wolf paw"] = 70, + ["wolf tooth chain"] = 100, + ["wolf trophy"] = 3000, + ["wood"] = 5, + ["wood mushroom"] = 15, + ["wooden hammer"] = 15, + ["wooden shield"] = 5, + ["wool"] = 15, + ["writhing brain"] = 370000, + ["writhing heart"] = 185000, + ["wyrm scale"] = 400, + ["wyvern fang"] = 1500, + ["wyvern talisman"] = 265, + ["yellow gem"] = 1000, + ["yellow piece of cloth"] = 150, + ["yielocks"] = 600, + ["yielowax"] = 600, + ["yirkas' egg"] = 280, + ["young lich worm"] = 25000, + ["zaoan armor"] = 14000, + ["zaoan halberd"] = 500, + ["zaoan helmet"] = 45000, + ["zaoan legs"] = 14000, + ["zaoan robe"] = 12000, + ["zaoan shoes"] = 5000, + ["zaoan sword"] = 30000, + ["zaogun flag"] = 600, + ["zaogun shoulderplates"] = 150, + -- supplies + ["mana potion"] = 56, + ["strong mana potion"] = 93, + ["great mana potion"] = 144, + ["ultimate mana potion"] = 438, + ["health potion"] = 50, + ["strong health potion"] = 115, + ["great health potion"] = 225, + ["ultimate health potion"] = 379, + ["supreme health potion"] = 625, + ["great spirit potion"] = 228, + ["ultimate spirit potion"] = 438 +} \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/z_items_management.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/items_management.lua similarity index 98% rename from modules/game_bot/default_configs/vBot/z_items_management.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/items_management.lua index a8704fa..bddb262 100644 --- a/modules/game_bot/default_configs/vBot/z_items_management.lua +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/items_management.lua @@ -1,5 +1,4 @@ setDefaultTab("Tools") -UI.Separator() UI.Label("Items Management") UI.Separator() diff --git a/modules/game_bot/default_configs/vBot/jewellery_equipper.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/jewellery_equipper.lua similarity index 99% rename from modules/game_bot/default_configs/vBot/jewellery_equipper.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/jewellery_equipper.lua index c483965..b5857f2 100644 --- a/modules/game_bot/default_configs/vBot/jewellery_equipper.lua +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/jewellery_equipper.lua @@ -300,6 +300,8 @@ Panel safeRingVal = manapercent() end + + -- [[ condition list ]] -- local ringEnabled = storage[panelName].ringEnabled local ringEquipped = getFinger() and (getFinger():getId() == storage[panelName].ringId or getFinger():getId() == getActiveItemId(storage[panelName].ringId)) diff --git a/modules/game_bot/default_configs/vBot/0_AAmain.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/main.lua similarity index 61% rename from modules/game_bot/default_configs/vBot/0_AAmain.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/main.lua index 3552668..d3d5b9b 100644 --- a/modules/game_bot/default_configs/vBot/0_AAmain.lua +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/main.lua @@ -1,4 +1,3 @@ --- main tab -UI.Label("vBot 1.3 \n Vithrax#5814") +UI.Label("vBot 2.0 \n Vithrax#5814") UI.Button("Official OTCv8 Discord!", function() g_platform.openUrl("https://discord.gg/yhqBE4A") end) UI.Separator() \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_2.01/vBot/new_cavebot_lib.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/new_cavebot_lib.lua new file mode 100644 index 0000000..056ab81 --- /dev/null +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/new_cavebot_lib.lua @@ -0,0 +1,456 @@ +CaveBot = {} -- global namespace + +------------------------------------------------------------------- +-- CaveBot lib 1.0 +-- Contains a universal set of functions to be used in CaveBot + +----------------------[[ basic assumption ]]----------------------- +-- in general, functions cannot be slowed from within, only externally, by event calls, delays etc. +-- considering that and the fact that there is no while loop, every function return action +-- thus, functions will need to be verified outside themselfs or by another function +-- overall tips to creating extension: +-- - functions return action(nil) or true(done) +-- - extensions are controlled by retries var +------------------------------------------------------------------- + +-- local variables, constants and functions, used by global functions +local LOCKERS_LIST = {3497, 3498, 3499, 3500} + +local function CaveBotConfigParse() + local name = storage["_configs"]["targetbot_configs"]["selected"] + local file = configDir .. "/targetbot_configs/" .. name .. ".json" + local data = g_resources.readFileContents(file) + return Config.parse(data)['looting'] +end + +local function getNearTiles(pos) + if type(pos) ~= "table" then + pos = pos:getPosition() + end + + local tiles = {} + local dirs = { + {-1, 1}, + {0, 1}, + {1, 1}, + {-1, 0}, + {1, 0}, + {-1, -1}, + {0, -1}, + {1, -1} + } + for i = 1, #dirs do + local tile = + g_map.getTile( + { + x = pos.x - dirs[i][1], + y = pos.y - dirs[i][2], + z = pos.z + } + ) + if tile then + table.insert(tiles, tile) + end + end + + return tiles +end + +-- ##################### -- +-- [[ Information class ]] -- +-- ##################### -- + +--- global variable to reflect current CaveBot status +CaveBot.Status = "waiting" + +--- Parses config and extracts loot list. +-- @return table +function CaveBot.GetLootItems() + local t = CaveBotConfigParse()["items"] + + local returnTable = {} + for i, item in pairs(t) do + table.insert(returnTable, item["id"]) + end + + return returnTable +end + +--- Parses config and extracts loot containers. +-- @return table +function CaveBot.GetLootContainers() + local t = CaveBotConfigParse()["containers"] + + local returnTable = {} + for i, container in pairs(t) do + table.insert(returnTable, container["id"]) + end + + return returnTable +end + +--- Information about open containers. +-- @param amount is boolean +-- @return table or integer +function CaveBot.GetOpenedLootContainers(containerTable) + local containers = CaveBot.GetLootContainers() + + local t = {} + for i, container in pairs(getContainers()) do + local containerId = container:getContainerItem():getId() + if table.find(containers, containerId) then + table.insert(t, container) + end + end + + return containerTable and t or #t +end + +--- Some actions needs to be additionally slowed down in case of high ping. +-- Maximum at 2000ms in case of lag spike. +-- @param multiplayer is integer +-- @return void +function CaveBot.PingDelay(multiplayer) + multiplayer = multiplayer or 1 + if ping() and ping() > 150 then -- in most cases ping above 150 affects CaveBot + local value = math.min(ping() * multiplayer, 2000) + return delay(value) + end +end + +-- ##################### -- +-- [[ Container class ]] -- +-- ##################### -- + +--- Closes any loot container that is open. +-- @return void or boolean +function CaveBot.CloseLootContainer() + local containers = CaveBot.GetLootContainers() + + for i, container in pairs(getContainers()) do + local containerId = container:getContainerItem():getId() + if table.find(containers, containerId) then + return g_game.close(container) + end + end + + return true +end + +--- Opens any loot container that isn't already opened. +-- @return void or boolean +function CaveBot.OpenLootContainer() + local containers = CaveBot.GetLootContainers() + + local t = {} + for i, container in pairs(getContainers()) do + local containerId = container:getContainerItem():getId() + table.insert(t, containerId) + end + + for _, container in pairs(getContainers()) do + for _, item in pairs(container:getItems()) do + local id = item:getId() + if table.find(containers, id) and not table.find(t, id) then + test() + return g_game.open(item) + end + end + end + + return true +end + +-- ##################### -- +-- [[[ Position class ]] -- +-- ##################### -- + +--- Compares distance between player position and given pos. +-- @param position is table +-- @param distance is integer +-- @return boolean +function CaveBot.MatchPosition(position, distance) + local pPos = player:getPosition() + distance = distance or 1 + return getDistanceBetween(pPos, position) <= distance +end + +--- Stripped down to take less space. +-- Use only to safe position, like pz movement or reaching npc. +-- Needs to be called between 200-500ms to achieve fluid movement. +-- @param position is table +-- @param distance is integer +-- @return void +function CaveBot.GoTo(position, precision) + if not precision then + precision = 3 + end + return CaveBot.walkTo(position, 20, {ignoreNonPathable = true, precision = precision}) +end + +--- Finds position of npc by name and reaches its position. +-- @return void(acion) or boolean +function CaveBot.ReachNPC(name) + name = name:lower() + + local npc = nil + for i, spec in pairs(getSpectators()) do + if spec:isNpc() and spec:getName():lower() == name then + npc = spec + end + end + + if not CaveBot.MatchPosition(npc:getPosition(), 3) then + CaveBot.GoTo(npc:getPosition()) + else + return true + end +end + +-- ##################### -- +-- [[[[ Depot class ]]]] -- +-- ##################### -- + +--- Reaches closest locker. +-- @return void(acion) or boolean +function CaveBot.ReachDepot() + local pPos = player:getPosition() + local tiles = getNearTiles(player:getPosition()) + + for i, tile in pairs(tiles) do + for i, item in pairs(tile:getItems()) do + if table.find(LOCKERS_LIST, item:getId()) then + return true -- if near locker already then return function + end + end + end + + local candidate = {} + + for i, tile in pairs(g_map.getTiles(posz())) do + local tPos = tile:getPosition() + local distance = getDistanceBetween(pPos, tPos) + for i, item in pairs(tile:getItems()) do + if table.find(LOCKERS_LIST, item:getId()) then + if findPath(pos(), tPos, 10, {ignoreNonPathable = true, precision = 1}) then + if #candidate == 0 or candidate.dist < distance then + candidate = {pos = tPos, dist = distance} + end + end + end + end + end + + if candidate.pos then + if not CaveBot.MatchPosition(candidate.pos) then + CaveBot.GoTo(candidate.pos, 1) + else + return true + end + end +end + +--- Opens locker item. +-- @return void(acion) or boolean +function CaveBot.OpenLocker() + local pPos = player:getPosition() + local tiles = getNearTiles(player:getPosition()) + + local locker = getContainerByName("Locker") + if not locker then + for i, tile in pairs(tiles) do + for i, item in pairs(tile:getItems()) do + if table.find(LOCKERS_LIST, item:getId()) then + local topThing = tile:getTopUseThing() + if not topThing:isNotMoveable() then + g_game.move(topThing, pPos, topThing:getCount()) + else + return g_game.open(item) + end + end + end + end + else + return true + end +end + +--- Opens depot chest. +-- @return void(acion) or boolean +function CaveBot.OpenDepotChest() + local depot = getContainerByName("Depot chest") + if not depot then + local locker = getContainerByName("Locker") + if not locker then + return CaveBot.OpenLocker() + end + for i, item in pairs(locker:getItems()) do + if item:getId() == 3502 then + return g_game.open(item, locker) + end + end + else + return true + end +end + +--- Opens inbox inside locker. +-- @return void(acion) or boolean +function CaveBot.OpenInbox() + local inbox = getContainerByName("Your inbox") + if not inbox then + local locker = getContainerByName("Locker") + if not locker then + return CaveBot.OpenLocker() + end + for i, item in pairs(locker:getItems()) do + if item:getId() == 12902 then + return g_game.open(item) + end + end + else + return true + end +end + +--- Opens depot box of given number. +-- @param index is integer +-- @return void or boolean +function CaveBot.OpenDepotBox(index) + local depot = getContainerByName("Depot chest") + if not depot then + return CaveBot.OpenDepotChest() + end + + local foundParent = false + for i, container in pairs(getContainers()) do + if container:getName():lower():find("depot box") then + foundParent = container + break + end + end + if foundParent then return true end + + for i, container in pairs(depot:getItems()) do + if i == index then + return g_game.open(container) + end + end +end + +--- Reaches and opens depot. +-- Combined for shorthand usage. +-- @return boolean whether succeed to reach and open depot +function CaveBot.ReachAndOpenDepot() + if CaveBot.ReachDepot() and CaveBot.OpenDepotChest() then + return true + end + return false +end + +--- Reaches and opens imbox. +-- Combined for shorthand usage. +-- @return boolean whether succeed to reach and open depot +function CaveBot.ReachAndOpenInbox() + if CaveBot.ReachDepot() and CaveBot.OpenInbox() then + return true + end + return false +end + +--- Stripped down function to stash item. +-- @param item is object +-- @param index is integer +-- @param destination is object +-- @return void +function CaveBot.StashItem(item, index, destination) + local depotContainer + if not destination then + depotContainer = getContainerByName("Depot chest") + end + if not depotContainer then return false end + + return g_game.move(item, depotContainer:getSlotPosition(index), item:getCount()) +end + +--- Withdraws item from depot chest or mail inbox. +-- main function for depositer/withdrawer +-- @param id is integer +-- @param amount is integer +-- @param fromDepot is boolean or integer +-- @param destination is object +-- @return void +function CaveBot.WithdrawItem(id, amount, fromDepot, destination) + if destination and type(destination) == "string" then + destination = getContainerByName(destination) + end + local itemCount = itemAmount(id) + + local depot + for i, container in pairs(getContainers()) do + if container:getName():lower():find("depot box") or container:getName():lower():find("your inbox") then + depot = container + break + end + end + if not depot then + if fromDepot then + if not CaveBot.OpenDepotBox(fromDepot) then return end + else + return CaveBot.ReachAndOpenInbox() + end + return + end + if not destination then + for i, container in pairs(getContainers()) do + if container:getCapacity() > #container:getItems() and not string.find(container:getName():lower(), "quiver") and not string.find(container:getName():lower(), "depot") and not string.find(container:getName():lower(), "loot") and not string.find(container:getName():lower(), "inbox") then + destination = container + end + end + end + + if itemCount >= amount then + return true + end + + local toMove = amount - itemCount + info(toMove) + for i, item in pairs(depot:getItems()) do + if item:getId() == id then + return g_game.move(item, destination:getSlotPosition(destination:getItemsCount()), math.min(toMove, item:getCount())) + end + end +end + +-- ##################### -- +-- [[[[[ Talk class ]]]] -- +-- ##################### -- + +--- Controlled by event caller. +-- Simple way to build npc conversations instead of multiline overcopied code. +-- @return void +function CaveBot.Conversation(...) + local expressions = {...} + local delay = storage.extras.talkDelay or 1000 + + local talkDelay = 0 + for i, expr in ipairs(expressions) do + schedule(talkDelay, function() NPC.say(expr) end) + talkDelay = talkDelay + delay + end +end + +--- Says hi trade to NPC. +-- Used as shorthand to open NPC trade window. +-- @return void +function CaveBot.OpenNpcTrade() + return CaveBot.Conversation("hi", "trade") +end + +--- Says hi destination yes to NPC. +-- Used as shorthand to travel. +-- @param destination is string +-- @return void +function CaveBot.Travel(destination) + return CaveBot.Conversation("hi", destination, "yes") +end \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/player_list.otui b/modules/game_bot/default_configs/vBot_2.01/vBot/player_list.otui similarity index 100% rename from modules/game_bot/default_configs/vBot/player_list.otui rename to modules/game_bot/default_configs/vBot_2.01/vBot/player_list.otui diff --git a/modules/game_bot/default_configs/vBot/playerlist.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/playerlist.lua similarity index 85% rename from modules/game_bot/default_configs/vBot/playerlist.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/playerlist.lua index 4bd2692..5da26e2 100644 --- a/modules/game_bot/default_configs/vBot/playerlist.lua +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/playerlist.lua @@ -1,3 +1,4 @@ +setDefaultTab("Main") local listPanelName = "playerList" local ui = setupUI([[ Panel @@ -8,6 +9,7 @@ Panel anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right + background: #292A2A height: 18 text: Player Lists ]], parent) @@ -81,7 +83,6 @@ Panel end label:setText(friendName) playerListWindow.FriendName:setText('') - refreshStatus() end end @@ -107,7 +108,6 @@ Panel end label:setText(friendName) playerListWindow.FriendName:setText('') - refreshStatus() end end @@ -122,7 +122,6 @@ Panel end label:setText(enemyName) playerListWindow.EnemyName:setText('') - refreshStatus() end end @@ -150,20 +149,20 @@ Panel playerListWindow:hide() end -function refreshStatus() +local refreshStatus = function() for _, spec in ipairs(getSpectators()) do if spec:isPlayer() and not spec:isLocalPlayer() then if storage[listPanelName].outfits then - specOutfit = spec:getOutfit() - if isEnemy(spec:getName()) then - spec:setMarked('#FF0000') - specOutfit.head = 112 - specOutfit.body = 112 - specOutfit.legs = 112 - specOutfit.feet = 112 - spec:setOutfit(specOutfit) - elseif isFriend(spec:getName()) then + local specOutfit = spec:getOutfit() + if isFriend(spec:getName()) then spec:setMarked('#0000FF') + specOutfit.head = 88 + specOutfit.body = 88 + specOutfit.legs = 88 + specOutfit.feet = 88 + spec:setOutfit(specOutfit) + elseif isEnemy(spec:getName()) then + spec:setMarked('#FF0000') specOutfit.head = 94 specOutfit.body = 94 specOutfit.legs = 94 @@ -176,8 +175,37 @@ function refreshStatus() end refreshStatus() +local checkStatus = function(creature) + if not creature:isPlayer() or creature:isLocalPlayer() then return end + + local specName = creature:getName() + local specOutfit = creature:getOutfit() + + if isFriend(specName) then + creature:setMarked('#0000FF') + specOutfit.head = 88 + specOutfit.body = 88 + specOutfit.legs = 88 + specOutfit.feet = 88 + creature:setOutfit(specOutfit) + elseif isEnemy(specName) then + creature:setMarked('#FF0000') + specOutfit.head = 94 + specOutfit.body = 94 + specOutfit.legs = 94 + specOutfit.feet = 94 + creature:setOutfit(specOutfit) + end +end + onCreatureAppear(function(creature) - if creature:isPlayer() then - refreshStatus() + checkStatus(creature) +end) + +onPlayerPositionChange(function(x,y) + if x.z ~= y.z then + schedule(20, function() + refreshStatus() + end) end end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_2.01/vBot/pushmax.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/pushmax.lua new file mode 100644 index 0000000..1729460 --- /dev/null +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/pushmax.lua @@ -0,0 +1,217 @@ +setDefaultTab("Main") + +local panelName = "pushmax" +local ui = setupUI([[ +Panel + height: 19 + + BotSwitch + id: title + anchors.top: parent.top + anchors.left: parent.left + text-align: center + width: 130 + !text: tr('PUSHMAX') + + Button + id: push + anchors.top: prev.top + anchors.left: prev.right + anchors.right: parent.right + margin-left: 3 + height: 17 + text: Setup + +]]) +ui:setId(panelName) + +if not storage[panelName] then + storage[panelName] = { + enabled = true, + pushDelay = 1060, + pushMaxRuneId = 3188, + mwallBlockId = 2128, + pushMaxKey = "PageUp" + } +end + +ui.title:setOn(storage[panelName].enabled) +ui.title.onClick = function(widget) +storage[panelName].enabled = not storage[panelName].enabled +widget:setOn(storage[panelName].enabled) +end + +ui.push.onClick = function(widget) + pushWindow:show() + pushWindow:raise() + pushWindow:focus() +end + +rootWidget = g_ui.getRootWidget() +if rootWidget then + pushWindow = UI.createWindow('PushMaxWindow', rootWidget) + pushWindow:hide() + + pushWindow.closeButton.onClick = function(widget) + pushWindow:hide() + end + + local updateDelayText = function() + pushWindow.delayText:setText("Push Delay: ".. storage[panelName].pushDelay) + end + updateDelayText() + pushWindow.delay.onValueChange = function(scroll, value) + storage[panelName].pushDelay = value + updateDelayText() + end + pushWindow.delay:setValue(storage[panelName].pushDelay) + + pushWindow.runeId.onItemChange = function(widget) + storage[panelName].pushMaxRuneId = widget:getItemId() + end + pushWindow.runeId:setItemId(storage[panelName].pushMaxRuneId) + pushWindow.mwallId.onItemChange = function(widget) + storage[panelName].mwallBlockId = widget:getItemId() + end + pushWindow.mwallId:setItemId(storage[panelName].mwallBlockId) + + pushWindow.hotkey.onTextChange = function(widget, text) + storage[panelName].pushMaxKey = text + end + pushWindow.hotkey:setText(storage[panelName].pushMaxKey) +end + + +-- variables for config + +local config = storage[panelName] +local pushDelay = tonumber(config.pushDelay) +local rune = tonumber(config.pushMaxRuneId) +local customMwall = config.mwallBlockId +local key = config.pushMaxKey +local enabled = config.enabled +local fieldTable = {2118, 105, 2122} + +-- scripts + +local targetTile +local pushTarget +local targetid + +local resetData = function() + for i, tile in pairs(g_map.getTiles(posz())) do + if tile:getText() == "TARGET" or tile:getText() == "DEST" then + tile:setText('') + end + end + pushTarget = nil + targetTile = nil + targetId = nil +end + +local getCreatureById = function(id) + for i, spec in ipairs(getSpectators()) do + if spec:getId() == id then + return spec + end + end + return false +end + +local isNotOk = function(t,tile) + local tileItems = {} + + for i, item in pairs(tile:getItems()) do + table.insert(tileItems, item:getId()) + end + for i, field in ipairs(t) do + if table.find(tileItems, field) then + return true + end + end + return false +end + +local isOk = function(a,b) + return getDistanceBetween(a,b) == 1 +end + +-- to mark +onKeyDown(function(keys) + if not enabled then return end + if keys ~= key then return end + local tile = getTileUnderCursor() + if not tile then return end + if pushTarget and targetTile then + resetData() + return + end + local creature = tile:getCreatures()[1] + if not pushTarget and creature then + pushTarget = creature + targetId = creature:getId() + if pushTarget then + tile:setText('TARGET') + pushTarget:setMarked('#00FF00') + end + elseif not targetTile and pushTarget then + if pushTarget and getDistanceBetween(tile:getPosition(),pushTarget:getPosition()) ~= 1 then + resetData() + return + else + tile:setText('DEST') + targetTile = tile + end + end +end) + +onCreaturePositionChange(function(creature, newPos, oldPos) + if not enabled then return end + if creature == player then + resetData() + end + if not pushTarget or not targetTile then return end + if creature == pushTarget and newPos == targetTile then + resetData() + end +end) + +macro(20, function() + if not enabled then return end + if not pushTarget or not targetTile then return end + tilePos = targetTile:getPosition() + targetPos = pushTarget:getPosition() + if not isOk(tilePos,targetPos) then return end + + local tileOfTarget = g_map.getTile(targetPos) + + if not targetTile:isWalkable() then + local topThing = targetTile:getTopUseThing():getId() + if topThing == 2129 or topThing == 2130 or topThing == customMwall then + if targetTile:getTimer() < pushDelay+500 then + storage.isUsing = true + schedule(pushDelay+700, function() + storage.isUsing = false + end) + end + if targetTile:getTimer() > pushDelay then + return + end + else + return resetData() + end + end + + if not tileOfTarget:getTopUseThing():isNotMoveable() then + return useWith(rune, pushTarget) + end + if isNotOk(fieldTable, targetTile) then + if targetTile:canShoot() then + return useWith(3148, targetTile:getTopUseThing()) + else + return + end + end + g_game.move(pushTarget,tilePos) + delay(2000) +end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot/pushmax.otui b/modules/game_bot/default_configs/vBot_2.01/vBot/pushmax.otui similarity index 85% rename from modules/game_bot/default_configs/vBot/pushmax.otui rename to modules/game_bot/default_configs/vBot_2.01/vBot/pushmax.otui index 7f38084..875a4f8 100644 --- a/modules/game_bot/default_configs/vBot/pushmax.otui +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/pushmax.otui @@ -67,18 +67,6 @@ PushMaxWindow < MainWindow margin-top: 5 text-align: center - Label - id: label - anchors.top: hotkey.bottom - anchors.horizontalCenter: parent.horizontalCenter - margin-top: 10 - text-align: center - text: Made by Frosty - font: cipsoftFont - image-source: /images/ui/window - image-border: 1 - width: 100 - HorizontalSeparator id: separator anchors.right: parent.right diff --git a/modules/game_bot/default_configs/vBot/z_quiver_manager.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/quiver_manager.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/z_quiver_manager.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/quiver_manager.lua diff --git a/modules/game_bot/default_configs/vBot/siolist.otui b/modules/game_bot/default_configs/vBot_2.01/vBot/siolist.otui similarity index 100% rename from modules/game_bot/default_configs/vBot/siolist.otui rename to modules/game_bot/default_configs/vBot_2.01/vBot/siolist.otui diff --git a/modules/game_bot/default_configs/vBot/spy_level.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/spy_level.lua similarity index 100% rename from modules/game_bot/default_configs/vBot/spy_level.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/spy_level.lua diff --git a/modules/game_bot/default_configs/vBot/supplies.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/supplies.lua similarity index 52% rename from modules/game_bot/default_configs/vBot/supplies.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/supplies.lua index 446fed0..35ae648 100644 --- a/modules/game_bot/default_configs/vBot/supplies.lua +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/supplies.lua @@ -4,22 +4,8 @@ function SuppliesPanel(parent) parent = panel end -local ui = setupUI([[ -Panel - height: 21 - - Button - id: supplies - anchors.left: parent.left - anchors.right: parent.right - text-align: center - !text: tr('Supplies') - -]]) -ui:setId(suppliesPanelName) - -if not storage[suppliesPanelName] then -storage[suppliesPanelName] = { +if not SuppliesConfig[suppliesPanelName] then +SuppliesConfig[suppliesPanelName] = { item1 = 0, item2 = 0, item3 = 0, @@ -58,232 +44,233 @@ if rootWidget then SuppliesWindow = g_ui.createWidget('SuppliesWindow', rootWidget) SuppliesWindow:hide() - SuppliesWindow.capSwitch:setOn(storage[suppliesPanelName].capSwitch) + SuppliesWindow.capSwitch:setOn(SuppliesConfig[suppliesPanelName].capSwitch) SuppliesWindow.capSwitch.onClick = function(widget) - storage[suppliesPanelName].capSwitch = not storage[suppliesPanelName].capSwitch - widget:setOn(storage[suppliesPanelName].capSwitch) + SuppliesConfig[suppliesPanelName].capSwitch = not SuppliesConfig[suppliesPanelName].capSwitch + widget:setOn(SuppliesConfig[suppliesPanelName].capSwitch) end - SuppliesWindow.SoftBoots:setOn(storage[suppliesPanelName].SoftBoots) + SuppliesWindow.SoftBoots:setOn(SuppliesConfig[suppliesPanelName].SoftBoots) SuppliesWindow.SoftBoots.onClick = function(widget) - storage[suppliesPanelName].SoftBoots = not storage[suppliesPanelName].SoftBoots - widget:setOn(storage[suppliesPanelName].SoftBoots) + SuppliesConfig[suppliesPanelName].SoftBoots = not SuppliesConfig[suppliesPanelName].SoftBoots + widget:setOn(SuppliesConfig[suppliesPanelName].SoftBoots) end - SuppliesWindow.imbues:setOn(storage[suppliesPanelName].imbues) + SuppliesWindow.imbues:setOn(SuppliesConfig[suppliesPanelName].imbues) SuppliesWindow.imbues.onClick = function(widget) - storage[suppliesPanelName].imbues = not storage[suppliesPanelName].imbues - widget:setOn(storage[suppliesPanelName].imbues) + SuppliesConfig[suppliesPanelName].imbues = not SuppliesConfig[suppliesPanelName].imbues + widget:setOn(SuppliesConfig[suppliesPanelName].imbues) end - SuppliesWindow.staminaSwitch:setOn(storage[suppliesPanelName].staminaSwitch) + SuppliesWindow.staminaSwitch:setOn(SuppliesConfig[suppliesPanelName].staminaSwitch) SuppliesWindow.staminaSwitch.onClick = function(widget) - storage[suppliesPanelName].staminaSwitch = not storage[suppliesPanelName].staminaSwitch - widget:setOn(storage[suppliesPanelName].staminaSwitch) + SuppliesConfig[suppliesPanelName].staminaSwitch = not SuppliesConfig[suppliesPanelName].staminaSwitch + widget:setOn(SuppliesConfig[suppliesPanelName].staminaSwitch) end - SuppliesWindow.SortSupplies:setOn(storage[suppliesPanelName].sortSupplies) + SuppliesWindow.SortSupplies:setOn(SuppliesConfig[suppliesPanelName].sortSupplies) SuppliesWindow.SortSupplies.onClick = function(widget) - storage[suppliesPanelName].sortSupplies = not storage[suppliesPanelName].sortSupplies - widget:setOn(storage[suppliesPanelName].sortSupplies) + SuppliesConfig[suppliesPanelName].sortSupplies = not SuppliesConfig[suppliesPanelName].sortSupplies + widget:setOn(SuppliesConfig[suppliesPanelName].sortSupplies) end -- bot items - SuppliesWindow.item1:setItemId(storage[suppliesPanelName].item1) + SuppliesWindow.item1:setItemId(SuppliesConfig[suppliesPanelName].item1) SuppliesWindow.item1.onItemChange = function(widget) - storage[suppliesPanelName].item1 = widget:getItemId() + SuppliesConfig[suppliesPanelName].item1 = widget:getItemId() end - SuppliesWindow.item2:setItemId(storage[suppliesPanelName].item2) + SuppliesWindow.item2:setItemId(SuppliesConfig[suppliesPanelName].item2) SuppliesWindow.item2.onItemChange = function(widget) - storage[suppliesPanelName].item2 = widget:getItemId() + SuppliesConfig[suppliesPanelName].item2 = widget:getItemId() end - SuppliesWindow.item3:setItemId(storage[suppliesPanelName].item3) + SuppliesWindow.item3:setItemId(SuppliesConfig[suppliesPanelName].item3) SuppliesWindow.item3.onItemChange = function(widget) - storage[suppliesPanelName].item3 = widget:getItemId() + SuppliesConfig[suppliesPanelName].item3 = widget:getItemId() end - SuppliesWindow.item4:setItemId(storage[suppliesPanelName].item4) + SuppliesWindow.item4:setItemId(SuppliesConfig[suppliesPanelName].item4) SuppliesWindow.item4.onItemChange = function(widget) - storage[suppliesPanelName].item4 = widget:getItemId() + SuppliesConfig[suppliesPanelName].item4 = widget:getItemId() end - SuppliesWindow.item5:setItemId(storage[suppliesPanelName].item5) + SuppliesWindow.item5:setItemId(SuppliesConfig[suppliesPanelName].item5) SuppliesWindow.item5.onItemChange = function(widget) - storage[suppliesPanelName].item5 = widget:getItemId() + SuppliesConfig[suppliesPanelName].item5 = widget:getItemId() end - SuppliesWindow.item6:setItemId(storage[suppliesPanelName].item6) + SuppliesWindow.item6:setItemId(SuppliesConfig[suppliesPanelName].item6) SuppliesWindow.item6.onItemChange = function(widget) - storage[suppliesPanelName].item6 = widget:getItemId() + SuppliesConfig[suppliesPanelName].item6 = widget:getItemId() end - SuppliesWindow.PotionBp:setItemId(storage[suppliesPanelName].potionBp) + SuppliesWindow.PotionBp:setItemId(SuppliesConfig[suppliesPanelName].potionBp) SuppliesWindow.PotionBp.onItemChange = function(widget) - storage[suppliesPanelName].potionBp = widget:getItemId() + SuppliesConfig[suppliesPanelName].potionBp = widget:getItemId() end - SuppliesWindow.RuneBp:setItemId(storage[suppliesPanelName].runeBp) + SuppliesWindow.RuneBp:setItemId(SuppliesConfig[suppliesPanelName].runeBp) SuppliesWindow.RuneBp.onItemChange = function(widget) - storage[suppliesPanelName].runeBp = widget:getItemId() + SuppliesConfig[suppliesPanelName].runeBp = widget:getItemId() end - SuppliesWindow.AmmoBp:setItemId(storage[suppliesPanelName].ammoBp) + SuppliesWindow.AmmoBp:setItemId(SuppliesConfig[suppliesPanelName].ammoBp) SuppliesWindow.AmmoBp.onItemChange = function(widget) - storage[suppliesPanelName].ammoBp = widget:getItemId() + SuppliesConfig[suppliesPanelName].ammoBp = widget:getItemId() end -- text windows - SuppliesWindow.capValue:setText(storage[suppliesPanelName].capValue) + SuppliesWindow.capValue:setText(SuppliesConfig[suppliesPanelName].capValue) SuppliesWindow.capValue.onTextChange = function(widget, text) local value = tonumber(SuppliesWindow.capValue:getText()) if not value then SuppliesWindow.capValue:setText(0) end - storage[suppliesPanelName].capValue = text + SuppliesConfig[suppliesPanelName].capValue = text end - SuppliesWindow.item1Min:setText(storage[suppliesPanelName].item1Min) + SuppliesWindow.item1Min:setText(SuppliesConfig[suppliesPanelName].item1Min) SuppliesWindow.item1Min.onTextChange = function(widget, text) local value = tonumber(SuppliesWindow.item1Min:getText()) if not value then SuppliesWindow.item1Min:setText(0) end - storage[suppliesPanelName].item1Min = text + SuppliesConfig[suppliesPanelName].item1Min = text end - SuppliesWindow.item1Max:setText(storage[suppliesPanelName].item1Max) + SuppliesWindow.item1Max:setText(SuppliesConfig[suppliesPanelName].item1Max) SuppliesWindow.item1Max.onTextChange = function(widget, text) local value = tonumber(SuppliesWindow.item1Max:getText()) if not value then SuppliesWindow.item1Max:setText(0) end - storage[suppliesPanelName].item1Max = text + SuppliesConfig[suppliesPanelName].item1Max = text end - SuppliesWindow.item2Min:setText(storage[suppliesPanelName].item2Min) + SuppliesWindow.item2Min:setText(SuppliesConfig[suppliesPanelName].item2Min) SuppliesWindow.item2Min.onTextChange = function(widget, text) local value = tonumber(SuppliesWindow.item2Min:getText()) if not value then SuppliesWindow.item2Min:setText(0) end - storage[suppliesPanelName].item2Min = text + SuppliesConfig[suppliesPanelName].item2Min = text end - SuppliesWindow.item2Max:setText(storage[suppliesPanelName].item2Max) + SuppliesWindow.item2Max:setText(SuppliesConfig[suppliesPanelName].item2Max) SuppliesWindow.item2Max.onTextChange = function(widget, text) local value = tonumber(SuppliesWindow.item2Max:getText()) if not value then SuppliesWindow.item2Max:setText(0) end - storage[suppliesPanelName].item2Max = text + SuppliesConfig[suppliesPanelName].item2Max = text end - SuppliesWindow.item3Min:setText(storage[suppliesPanelName].item3Min) + SuppliesWindow.item3Min:setText(SuppliesConfig[suppliesPanelName].item3Min) SuppliesWindow.item3Min.onTextChange = function(widget, text) local value = tonumber(SuppliesWindow.item3Min:getText()) if not value then SuppliesWindow.item3Min:setText(0) end - storage[suppliesPanelName].item3Min = text + SuppliesConfig[suppliesPanelName].item3Min = text end - SuppliesWindow.item3Max:setText(storage[suppliesPanelName].item3Max) + SuppliesWindow.item3Max:setText(SuppliesConfig[suppliesPanelName].item3Max) SuppliesWindow.item3Max.onTextChange = function(widget, text) local value = tonumber(SuppliesWindow.item3Max:getText()) if not value then SuppliesWindow.item3Max:setText(0) end - storage[suppliesPanelName].item3Max = text + SuppliesConfig[suppliesPanelName].item3Max = text end - SuppliesWindow.item4Min:setText(storage[suppliesPanelName].item4Min) + SuppliesWindow.item4Min:setText(SuppliesConfig[suppliesPanelName].item4Min) SuppliesWindow.item4Min.onTextChange = function(widget, text) local value = tonumber(SuppliesWindow.item4Min:getText()) if not value then SuppliesWindow.item4Min:setText(0) end - storage[suppliesPanelName].item4Min = text + SuppliesConfig[suppliesPanelName].item4Min = text end -SuppliesWindow.staminaValue:setText(storage[suppliesPanelName].staminaValue) +SuppliesWindow.staminaValue:setText(SuppliesConfig[suppliesPanelName].staminaValue) SuppliesWindow.staminaValue.onTextChange = function(widget, text) local value = tonumber(SuppliesWindow.staminaValue:getText()) if not value then SuppliesWindow.staminaValue:setText(0) end - storage[suppliesPanelName].staminaValue = text + SuppliesConfig[suppliesPanelName].staminaValue = text end - SuppliesWindow.item4Max:setText(storage[suppliesPanelName].item4Max) + SuppliesWindow.item4Max:setText(SuppliesConfig[suppliesPanelName].item4Max) SuppliesWindow.item4Max.onTextChange = function(widget, text) local value = tonumber(SuppliesWindow.item4Max:getText()) if not value then SuppliesWindow.item4Max:setText(0) end - storage[suppliesPanelName].item4Max = text + SuppliesConfig[suppliesPanelName].item4Max = text end - SuppliesWindow.item5Min:setText(storage[suppliesPanelName].item5Min) + SuppliesWindow.item5Min:setText(SuppliesConfig[suppliesPanelName].item5Min) SuppliesWindow.item5Min.onTextChange = function(widget, text) local value = tonumber(SuppliesWindow.item5Min:getText()) if not value then SuppliesWindow.item5Min:setText(0) end - storage[suppliesPanelName].item5Min = text + SuppliesConfig[suppliesPanelName].item5Min = text end - SuppliesWindow.item5Max:setText(storage[suppliesPanelName].item5Max) + SuppliesWindow.item5Max:setText(SuppliesConfig[suppliesPanelName].item5Max) SuppliesWindow.item5Max.onTextChange = function(widget, text) local value = tonumber(SuppliesWindow.item5Max:getText()) if not value then SuppliesWindow.item5Max:setText(0) end - storage[suppliesPanelName].item5Max = text + SuppliesConfig[suppliesPanelName].item5Max = text end -SuppliesWindow.item6Min:setText(storage[suppliesPanelName].item6Min) +SuppliesWindow.item6Min:setText(SuppliesConfig[suppliesPanelName].item6Min) SuppliesWindow.item6Min.onTextChange = function(widget, text) local value = tonumber(SuppliesWindow.item6Min:getText()) if not value then SuppliesWindow.item6Min:setText(0) end - storage[suppliesPanelName].item6Min = text + SuppliesConfig[suppliesPanelName].item6Min = text end -SuppliesWindow.item6Max:setText(storage[suppliesPanelName].item6Max) +SuppliesWindow.item6Max:setText(SuppliesConfig[suppliesPanelName].item6Max) SuppliesWindow.item6Max.onTextChange = function(widget, text) local value = tonumber(SuppliesWindow.item6Max:getText()) if not value then SuppliesWindow.item6Max:setText(0) end - storage[suppliesPanelName].item6Max = text + SuppliesConfig[suppliesPanelName].item6Max = text end end -ui.supplies.onClick = function(widget) +UI.Button("Supplies", function() SuppliesWindow:show() SuppliesWindow:raise() SuppliesWindow:focus() -end +end) SuppliesWindow.close.onClick = function(widget) SuppliesWindow:hide() + vBotConfigSave("supply") end end -local potions = {268, 237, 238, 23373, 266, 236, 239, 7643, 7642, 23374} +local potions = {23375, 268, 237, 238, 23373, 266, 236, 239, 7643, 7642, 23374} local runes = {3725, 3203, 3161, 3147, 3178, 3177, 3153, 3148, 3197, 3149, 3164, 3166, 3200, 3192, 3188, 3190, 3189, 3191, 3198, 3182, 3158, 3152, 3174, 3180, 3165, 3173, 3172, 3176, 3195, 3179, 3175, 3155, 3202, 3160, 3156} -local ammo = {23375, 3446, 16142, 6528, 7363, 3450, 16141, 25785, 14252, 3447, 3449, 15793, 25757, 774, 16143, 763, 761, 7365, 3448, 762, 21470, 7364, 14251, 7368, 25759, 3287, 7366, 3298, 25758} +local ammo = {3446, 16142, 6528, 7363, 3450, 16141, 25785, 14252, 3447, 3449, 15793, 25757, 774, 16143, 763, 761, 7365, 3448, 762, 21470, 7364, 14251, 7368, 25759, 3287, 7366, 3298, 25758} macro(250, function() - if not storage[suppliesPanelName].sortSupplies then return end - local sortPotions = storage[suppliesPanelName].potionBp > 100 - local sortRunes = storage[suppliesPanelName].runeBp > 100 - local sortAmmo = storage[suppliesPanelName].ammoBp > 100 + if not SuppliesConfig[suppliesPanelName].sortSupplies then return end + local sortPotions = SuppliesConfig[suppliesPanelName].potionBp > 100 + local sortRunes = SuppliesConfig[suppliesPanelName].runeBp > 100 + local sortAmmo = SuppliesConfig[suppliesPanelName].ammoBp > 100 local potionsContainer = nil local runesContainer = nil local ammoContainer = nil @@ -292,11 +279,11 @@ macro(250, function() if not potionsContainer or not runesContainer or not ammoContainer then for i, container in pairs(getContainers()) do if not containerIsFull(container) then - if sortPotions and container:getContainerItem():getId() == storage[suppliesPanelName].potionBp then + if sortPotions and container:getContainerItem():getId() == SuppliesConfig[suppliesPanelName].potionBp then potionsContainer = container - elseif sortRunes and container:getContainerItem():getId() == storage[suppliesPanelName].runeBp then + elseif sortRunes and container:getContainerItem():getId() == SuppliesConfig[suppliesPanelName].runeBp then runesContainer = container - elseif sortAmmo and container:getContainerItem():getId() == storage[suppliesPanelName].ammoBp then + elseif sortAmmo and container:getContainerItem():getId() == SuppliesConfig[suppliesPanelName].ammoBp then ammoContainer = container end end @@ -307,7 +294,7 @@ macro(250, function() -- potions if potionsContainer then for i, container in pairs(getContainers()) do - if (container:getContainerItem():getId() ~= storage[suppliesPanelName].potionBp and (string.find(container:getName(), "backpack") or string.find(container:getName(), "bag") or string.find(container:getName(), "chess"))) then + if (container:getContainerItem():getId() ~= SuppliesConfig[suppliesPanelName].potionBp and (string.find(container:getName(), "backpack") or string.find(container:getName(), "bag") or string.find(container:getName(), "chess"))) then for j, item in pairs(container:getItems()) do if table.find(potions, item:getId()) then return g_game.move(item, potionsContainer:getSlotPosition(potionsContainer:getItemsCount()), item:getCount()) @@ -320,7 +307,7 @@ macro(250, function() -- runes if runesContainer then for i, container in pairs(getContainers()) do - if (container:getContainerItem():getId() ~= storage[suppliesPanelName].runeBp and (string.find(container:getName(), "backpack") or string.find(container:getName(), "bag") or string.find(container:getName(), "chess"))) then + if (container:getContainerItem():getId() ~= SuppliesConfig[suppliesPanelName].runeBp and (string.find(container:getName(), "backpack") or string.find(container:getName(), "bag") or string.find(container:getName(), "chess"))) then for j, item in pairs(container:getItems()) do if table.find(runes, item:getId()) then return g_game.move(item, runesContainer:getSlotPosition(runesContainer:getItemsCount()), item:getCount()) @@ -333,7 +320,7 @@ macro(250, function() -- ammo if ammoContainer then for i, container in pairs(getContainers()) do - if (container:getContainerItem():getId() ~= storage[suppliesPanelName].ammoBp and (string.find(container:getName(), "backpack") or string.find(container:getName(), "bag") or string.find(container:getName(), "chess"))) and not string.find(container:getName():lower(), "loot") then + if (container:getContainerItem():getId() ~= SuppliesConfig[suppliesPanelName].ammoBp and (string.find(container:getName(), "backpack") or string.find(container:getName(), "bag") or string.find(container:getName(), "chess"))) and not string.find(container:getName():lower(), "loot") then for j, item in pairs(container:getItems()) do if table.find(ammo, item:getId()) then return g_game.move(item, ammoContainer:getSlotPosition(ammoContainer:getItemsCount()), item:getCount()) diff --git a/modules/game_bot/default_configs/vBot/supplies.otui b/modules/game_bot/default_configs/vBot_2.01/vBot/supplies.otui similarity index 99% rename from modules/game_bot/default_configs/vBot/supplies.otui rename to modules/game_bot/default_configs/vBot_2.01/vBot/supplies.otui index 0544051..eeb6da5 100644 --- a/modules/game_bot/default_configs/vBot/supplies.otui +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/supplies.otui @@ -1,7 +1,6 @@ SuppliesWindow < MainWindow !text: tr('Supplies') size: 430 310 - @onEscape: self:hide() VerticalSeparator id: sep diff --git a/modules/game_bot/default_configs/vBot/tools.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/tools.lua similarity index 58% rename from modules/game_bot/default_configs/vBot/tools.lua rename to modules/game_bot/default_configs/vBot_2.01/vBot/tools.lua index 5f7524e..b5491fb 100644 --- a/modules/game_bot/default_configs/vBot/tools.lua +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/tools.lua @@ -1,29 +1,6 @@ -- tools tab setDefaultTab("Tools") --- allows to test/edit bot lua scripts ingame, you can have multiple scripts like this, just change storage.ingame_lua -UI.Button("Ingame hotkey editor", function(newText) - UI.MultilineEditorWindow(storage.ingame_hotkeys or "", {title="Hotkeys editor", description="You can add your custom hotkeys/singlehotkeys here"}, function(text) - storage.ingame_hotkeys = text - reload() - end) -end) - -UI.Separator() - -for _, scripts in pairs({storage.ingame_hotkeys}) do - if type(scripts) == "string" and scripts:len() > 3 then - local status, result = pcall(function() - assert(load(scripts, "ingame_editor"))() - end) - if not status then - error("Ingame edior error:\n" .. result) - end - end -end - -UI.Separator() - local moneyIds = {3031, 3035} -- gold coin, platinium coin macro(1000, "Exchange money", function() local containers = g_game.getContainers() diff --git a/modules/game_bot/default_configs/vBot_2.01/vBot/vlib.lua b/modules/game_bot/default_configs/vBot_2.01/vBot/vlib.lua new file mode 100644 index 0000000..6e0a3a4 --- /dev/null +++ b/modules/game_bot/default_configs/vBot_2.01/vBot/vlib.lua @@ -0,0 +1,1067 @@ +-- Author: Vithrax +-- contains mostly basic function shortcuts and code shorteners +-- burst damage calculation, for function burstDamageValue() +-- sums monster hits on a span of last 3seconds +-- if last message was more than 3s ago then clears the table +local dmgTable = {} +local lastDmgMessage = now +onTextMessage(function(mode, text) + if not text:lower():find("you lose") or not text:lower():find("due to") then + return + end + local dmg = string.match(text, "%d+") + if #dmgTable > 0 then + for k, v in ipairs(dmgTable) do + if now - v.t > 3000 then table.remove(dmgTable, k) end + end + end + lastDmgMessage = now + table.insert(dmgTable, {d = dmg, t = now}) + schedule(3050, function() + if now - lastDmgMessage > 3000 then dmgTable = {} end + end) +end) + +-- based on data collected by callback calculates per second damage +-- returns number +function burstDamageValue() + local d = 0 + local time = 0 + if #dmgTable > 1 then + for i, v in ipairs(dmgTable) do + if i == 1 then time = v.t end + d = d + v.d + end + end + return math.ceil(d / ((now - time) / 1000)) +end + +-- simplified function from modules +-- displays string as white colour message +function whiteInfoMessage(text) + return modules.game_textmessage.displayGameMessage(text) +end + +-- almost every talk action inside cavebot has to be done by using schedule +-- therefore this is simplified function that doesn't require to build a body for schedule function +function scheduleNpcSay(text, delay) + if not text or not delay then return false end + + return schedule(delay, function() NPC.say(text) end) +end + +-- returns first number in string, already formatted as number +-- returns number or nil +function getFirstNumberInText(text) + local n = nil + if string.match(text, "%d+") then n = tonumber(string.match(text, "%d+")) end + return n +end + +-- function to search if item of given ID can be found on certain tile +-- first argument is always ID +-- the rest of aguments can be: +-- - tile +-- - position +-- - or x,y,z coordinates as p1, p2 and p3 +-- returns boolean +function isOnTile(id, p1, p2, p3) + if not id then return end + local tile + if type(p1) == "table" then + tile = g_map.getTile(p1) + elseif type(p1) ~= "number" then + tile = p1 + else + local p = getPos(p1, p2, p3) + tile = g_map.getTile(p) + end + if not tile then return end + + local item = false + if #tile:getItems() ~= 0 then + for i, v in ipairs(tile:getItems()) do + if v:getId() == id then item = true end + end + else + return false + end + + return item +end + +-- position is a special table, impossible to compare with normal one +-- this is translator from x,y,z to proper position value +-- returns position table +function getPos(x, y, z) + if not x or not y or not z then return nil end + local pos = pos() + pos.x = x + pos.y = y + pos.z = z + + return pos +end + +-- opens purse... that's it +function openPurse() + return g_game.use(g_game.getLocalPlayer():getInventoryItem( + InventorySlotPurse)) +end + +-- check's whether container is full +-- c has to be container object +-- returns boolean +function containerIsFull(c) + if not c then return false end + + if c:getCapacity() > #c:getItems() then + return false + else + return true + end + +end + +-- not perfect function to return whether character has utito tempo buff +-- known to be bugged if received debuff (ie. roshamuul) +-- TODO: simply a better version +-- returns boolean +function isBuffed() + local var = false + for i = 1, 4 do + local premium = (player:getSkillLevel(i) - player:getSkillBaseLevel(i)) + local base = player:getSkillBaseLevel(i) + if hasPartyBuff() and (premium / 100) * 305 > base then + var = true + end + end + return var +end + +-- if using index as table element, this can be used to properly assign new idex to all values +-- table needs to contain "index" as value +-- if no index in tables, it will create one +function reindexTable(t) + if not t or type(t) ~= "table" then return end + + local i = 0 + for _, e in pairs(t) do + i = i + 1 + e.index = i + end +end + +-- supports only new tibia, ver 10+ +-- returns how many kills left to get next skull - can be red skull, can be black skull! +-- reutrns number +function killsToRs() + return math.min(g_game.getUnjustifiedPoints().killsDayRemaining, + g_game.getUnjustifiedPoints().killsWeekRemaining, + g_game.getUnjustifiedPoints().killsMonthRemaining) +end + +-- calculates exhaust for potions based on "Aaaah..." message +-- changes state of storage variable, can be used in other scripts +-- already used in pushmax, healbot, etc +storage.isUsingPotion = false +onTalk(function(name, level, mode, text, channelId, pos) + if name ~= player:getName() then return end + if mode ~= 34 then return end + + if text == "Aaaah..." then + storage.isUsingPotion = true + schedule(950, function() storage.isUsingPotion = false end) + end +end) + +-- [[ canCast and cast functions ]] -- +-- callback connected to cast and canCast function +-- detects if a given spell was in fact casted based on player's text messages +-- Cast text and message text must match +-- checks only spells inserted in SpellCastTable by function cast +SpellCastTable = {} +onTalk(function(name, level, mode, text, channelId, pos) + if name ~= player:getName() then return end + + if SpellCastTable[text] then SpellCastTable[text].t = now end +end) + +-- if delay is nil or delay is lower than 100 then this function will act as a normal say function +-- checks or adds a spell to SpellCastTable and updates cast time if exist +function cast(text, delay) + if type(text) ~= "string" then return end + if not delay or delay < 100 then + return say(text) -- if not added delay or delay is really low then just treat it like casual say + end + if not SpellCastTable[text] or SpellCastTable[text].d ~= delay then + SpellCastTable[text] = {t = now - delay, d = delay} + return say(text) + end + local lastCast = SpellCastTable[text].t + local spellDelay = SpellCastTable[text].d + if now - lastCast > spellDelay then return say(text) end + return +end + +-- canCast is a base for AttackBot and HealBot +-- checks if spell is ready to be casted again +-- ignoreRL - if true, aparat from cooldown will also check conditions inside gamelib SpellInfo table +-- ignoreCd - it true, will ignore cooldown +-- returns boolean +local Spells = modules.gamelib.SpellInfo['Default'] +function canCast(spell, ignoreRL, ignoreCd) + if type(spell) ~= "string" then return end + spell = spell:lower() + if not getSpellData(spell) then + if SpellCastTable[spell] then + if now - SpellCastTable[spell].t > SpellCastTable[spell].d then + return true + else + return false + end + else + return true + end + end + if (ignoreCd or not getSpellCoolDown(spell)) and + (ignoreRL or level() >= getSpellData(spell).level and mana() >= + getSpellData(spell).mana) then + return true + else + return false + end +end + +-- exctracts data about spell from gamelib SpellInfo table +-- returns table +-- ie:['Spell Name'] = {id, words, exhaustion, premium, type, icon, mana, level, soul, group, vocations} +function getSpellData(spell) + if not spell then return false end + spell = spell:lower() + local t = nil + for k, v in pairs(Spells) do + if v.words == spell then + t = k + break + end + end + if t then + return Spells[t] + else + return false + end +end + +-- based on info extracted by getSpellData checks if spell is on cooldown +-- returns boolean +function getSpellCoolDown(text) + if not text then return false end + text = text:lower() + if not getSpellData(text) then return false end + for i, v in pairs(Spells) do + if v.words == text then + return modules.game_cooldown.isCooldownIconActive(v.id) + end + end +end + +-- global var to indicate that player is trying to do something +-- prevents action blocking by scripts +-- below callbacks are triggers to changing the var state +storage.isUsing = false +onUse(function(pos, itemId, stackPos, subType) + if pos.x < 65000 then storage.isUsing = true end + schedule(1500, + function() if storage.isUsing then storage.isUsing = false end end) +end) +onUseWith(function(pos, itemId, target, subType) + if itemId ~= 3180 then return end + if pos.x < 65000 then storage.isUsing = true end + schedule(1500, + function() if storage.isUsing then storage.isUsing = false end end) +end) + +-- returns first word in string +function string.starts(String, Start) + return string.sub(String, 1, string.len(Start)) == Start +end + +-- global tables for cached players to prevent unnecesary resource consumption +-- probably still can be improved, TODO in future +-- c can be creature or string +-- if exected then adds name or name and creature to tables +-- returns boolean +CachedFriends = {} +CachedNeutrals = {} +CachedEnemies = {} +function isFriend(c) + local name = c + if type(c) ~= "string" then + if c == player then return true end + name = c:getName() + if name == name() then return true end + end + + if CachedFriends[c] then return true end + if CachedNeutrals[c] or CachedEnemies[c] then return false end + + if table.find(storage.playerList.friendList, name) then + CachedFriends[c] = true + return true + elseif string.find(storage.serverMembers or "", name) then + CachedFriends[c] = true + return true + elseif storage.playerList.groupMembers then + local p = c + if type(c) == "string" then p = getCreatureByName(c, true) end + if not p then return false end + if p:isLocalPlayer() then return true end + if p:isPlayer() then + if ((p:getShield() >= 3 and p:getShield() <= 10) or p:getEmblem() == + 2) then + CachedFriends[c] = true + CachedFriends[p] = true + return true + else + CachedNeutrals[c] = true + CachedNeutrals[p] = true + return false + end + end + else + CachedNeutrals[c] = true + if c ~= p and p then + CachedNeutrals[p] = true + end + return false + end +end + +-- similar to isFriend but lighter version +-- accepts only name string +-- returns boolean +function isEnemy(name) + if not name then return false end + local p = getCreatureByName(name, true) + if not p then return end + if p:isLocalPlayer() then return end + + if p:isPlayer() and table.find(storage.playerList.enemyList, name) or + (storage.playerList.marks and not isFriend(name)) then + return true + else + return false + end +end + +-- based on first word in string detects if text is a offensive spell +-- returns boolean +function isAttSpell(expr) + if string.starts(expr, "exori") or string.starts(expr, "exevo") then + return true + else + return false + end +end + +-- returns dressed-up item id based on not dressed id +-- returns number +function getActiveItemId(id) + if not id then return false end + + if id == 3049 then + return 3086 + elseif id == 3050 then + return 3087 + elseif id == 3051 then + return 3088 + elseif id == 3052 then + return 3089 + elseif id == 3053 then + return 3090 + elseif id == 3091 then + return 3094 + elseif id == 3092 then + return 3095 + elseif id == 3093 then + return 3096 + elseif id == 3097 then + return 3099 + elseif id == 3098 then + return 3100 + elseif id == 16114 then + return 16264 + elseif id == 23531 then + return 23532 + elseif id == 23533 then + return 23534 + elseif id == 23529 then + return 23530 + else + return id + end +end + +-- returns not dressed item id based on dressed-up id +-- returns number +function getInactiveItemId(id) + if not id then return false end + + if id == 3086 then + return 3049 + elseif id == 3087 then + return 3050 + elseif id == 3088 then + return 3051 + elseif id == 3089 then + return 3052 + elseif id == 3090 then + return 3053 + elseif id == 3094 then + return 3091 + elseif id == 3095 then + return 3092 + elseif id == 3096 then + return 3093 + elseif id == 3099 then + return 3097 + elseif id == 3100 then + return 3098 + elseif id == 16264 then + return 16114 + elseif id == 23532 then + return 23531 + elseif id == 23534 then + return 23533 + elseif id == 23530 then + return 23529 + else + return id + end +end + +-- returns amount of monsters within the range of position +-- does not include summons (new tibia) +-- returns number +function getMonstersInRange(pos, range) + if not pos or not range then return false end + local monsters = 0 + for i, spec in pairs(getSpectators()) do + if spec:isMonster() and + (g_game.getClientVersion() < 960 or spec:getType() < 3) and + getDistanceBetween(pos, spec:getPosition()) < range then + monsters = monsters + 1 + end + end + return monsters +end + +-- shortcut in calculating distance from local player position +-- needs only one argument +-- returns number +function distanceFromPlayer(coords) + if not coords then return false end + return getDistanceBetween(pos(), coords) +end + +-- returns amount of monsters within the range of local player position +-- does not include summons (new tibia) +-- can also check multiple floors +-- returns number +function getMonsters(range, multifloor) + if not range then range = 10 end + local mobs = 0; + for _, spec in pairs(getSpectators(multifloor)) do + mobs = (g_game.getClientVersion() < 960 or spec:getType() < 3) and + spec:isMonster() and distanceFromPlayer(spec:getPosition()) <= + range and mobs + 1 or mobs; + end + return mobs; +end + +-- returns amount of players within the range of local player position +-- does not include party members +-- can also check multiple floors +-- returns number +function getPlayers(range, multifloor) + if not range then range = 10 end + local specs = 0; + for _, spec in pairs(getSpectators(multifloor)) do + specs = not spec:isLocalPlayer() and spec:isPlayer() and + distanceFromPlayer(spec:getPosition()) <= range and + not ((spec:getShield() >= 3 and spec:getShield() <= 10) or + spec:getEmblem() == 1) and specs + 1 or specs; + end + return specs; +end + +-- this is multifloor function +-- checks if player added in "Anti RS list" in player list is within the given range +-- returns boolean +function isBlackListedPlayerInRange(range) + if #storage.playerList.blackList == 0 then return end + if not range then range = 10 end + local found = false + for _, spec in pairs(getSpectators(true)) do + local specPos = spec:getPosition() + local pPos = player:getPosition() + if spec:isPlayer() then + if math.abs(specPos.z - pPos.z) <= 2 then + if specPos.z ~= pPos.z then specPos.z = pPos.z end + if distanceFromPlayer(specPos) < range then + if table.find(storage.playerList.blackList, spec:getName()) then + found = true + end + end + end + end + end + return found +end + +-- checks if there is non-friend player withing the range +-- padding is only for multifloor +-- returns boolean +function isSafe(range, multifloor, padding) + local onSame = 0 + local onAnother = 0 + if not multifloor and padding then + multifloor = false + padding = false + end + + for _, spec in pairs(getSpectators(multifloor)) do + if spec:isPlayer() and not spec:isLocalPlayer() and + not isFriend(spec:getName()) then + if spec:getPosition().z == posz() and + distanceFromPlayer(spec:getPosition()) <= range then + onSame = onSame + 1 + end + if multifloor and padding and spec:getPosition().z ~= posz() and + distanceFromPlayer(spec:getPosition()) <= (range + padding) then + onAnother = onAnother + 1 + end + end + end + + if onSame + onAnother > 0 then + return false + else + return true + end +end + +-- returns amount of players within the range of local player position +-- can also check multiple floors +-- returns number +function getAllPlayers(range, multifloor) + if not range then range = 10 end + local specs = 0; + for _, spec in pairs(getSpectators(multifloor)) do + specs = not spec:isLocalPlayer() and spec:isPlayer() and + distanceFromPlayer(spec:getPosition()) <= range and specs + + 1 or specs; + end + return specs; +end + +-- returns amount of NPC's within the range of local player position +-- can also check multiple floors +-- returns number +function getNpcs(range, multifloor) + if not range then range = 10 end + local npcs = 0; + for _, spec in pairs(getSpectators(multifloor)) do + npcs = + spec:isNpc() and distanceFromPlayer(spec:getPosition()) <= range and + npcs + 1 or npcs; + end + return npcs; +end + +-- main function for calculatin item amount in all visible containers +-- also considers equipped items +-- returns number +function itemAmount(id) + local totalItemCount = 0 + for _, container in pairs(getContainers()) do + if not container:getName():lower():find("depot") and not container:getName():lower():find("your inbox") then + for _, item in ipairs(container:getItems()) do + totalItemCount = item:getId() == id and totalItemCount + + item:getCount() or totalItemCount + end + end + end + if getHead() and getHead():getId() == id then + totalItemCount = totalItemCount + getHead():getCount() + end + if getNeck() and getNeck():getId() == id then + totalItemCount = totalItemCount + getNeck():getCount() + end + if getBack() and getBack():getId() == id then + totalItemCount = totalItemCount + getBack():getCount() + end + if getBody() and getBody():getId() == id then + totalItemCount = totalItemCount + getBody():getCount() + end + if getRight() and getRight():getId() == id then + totalItemCount = totalItemCount + getRight():getCount() + end + if getLeft() and getLeft():getId() == id then + totalItemCount = totalItemCount + getLeft():getCount() + end + if getLeg() and getLeg():getId() == id then + totalItemCount = totalItemCount + getLeg():getCount() + end + if getFeet() and getFeet():getId() == id then + totalItemCount = totalItemCount + getFeet():getCount() + end + if getFinger() and getFinger():getId() == id then + totalItemCount = totalItemCount + getFinger():getCount() + end + if getAmmo() and getAmmo():getId() == id then + totalItemCount = totalItemCount + getAmmo():getCount() + end + return totalItemCount +end + +-- self explanatory +-- a is item to use on +-- b is item to use a on +function useOnInvertoryItem(a, b) + local item = findItem(b) + if not item then return end + + return useWith(a, item) +end + +-- checks if player has at least 50% of minimal supplies given in Supplies window +-- returns boolean +function hasSupplies() + local supplies = SuppliesConfig.supplies + local items = { + {ID = supplies.item1, minAmount = supplies.item1Min}, + {ID = supplies.item2, minAmount = supplies.item2Min}, + {ID = supplies.item3, minAmount = supplies.item3Min}, + {ID = supplies.item4, minAmount = supplies.item4Min}, + {ID = supplies.item5, minAmount = supplies.item5Min}, + {ID = supplies.item6, minAmount = supplies.item6Min}, + {ID = supplies.item7, minAmount = supplies.item7Min} + } + -- false = no supplies + -- true = supplies available + + local hasSupplies = true + + for i, supply in pairs(items) do + if supply.minAmount and supply.ID then + if supply.ID > 100 and itemAmount(supply.ID) < + (supply.minAmount / 2) then hasSupplies = false end + end + end + + return hasSupplies +end + +-- pos can be tile or position +-- returns table of tiles surrounding given POS/tile +function getNearTiles(pos) + if type(pos) ~= "table" then pos = pos:getPosition() end + + local tiles = {} + local dirs = { + {-1, 1}, {0, 1}, {1, 1}, {-1, 0}, {1, 0}, {-1, -1}, {0, -1}, {1, -1} + } + for i = 1, #dirs do + local tile = g_map.getTile({ + x = pos.x - dirs[i][1], + y = pos.y - dirs[i][2], + z = pos.z + }) + if tile then table.insert(tiles, tile) end + end + + return tiles +end + +-- self explanatory +-- use along with delay, it will only call action +function useGroundItem(id) + if not id then return false end + + local dest = nil + for i, tile in ipairs(g_map.getTiles(posz())) do + for j, item in ipairs(tile:getItems()) do + if item:getId() == id then + dest = item + break + end + end + end + + if dest then + return use(dest) + else + return false + end +end + +-- self explanatory +-- use along with delay, it will only call action +function reachGroundItem(id) + if not id then return false end + + local dest = nil + for i, tile in ipairs(g_map.getTiles(posz())) do + for j, item in ipairs(tile:getItems()) do + local iPos = item:getPosition() + local iId = item:getId() + if iId == id then + if findPath(pos(), iPos, 20, + {ignoreNonPathable = true, precision = 1}) then + dest = item + break + end + end + end + end + + if dest then + return autoWalk(iPos, 20, {ignoreNonPathable = true, precision = 1}) + else + return false + end +end + +-- self explanatory +-- returns object +function findItemOnGround(id) + for i, tile in ipairs(g_map.getTiles(posz())) do + for j, item in ipairs(tile:getItems()) do + if item:getId() == id then return item end + end + end +end + +-- self explanatory +-- use along with delay, it will only call action +function useOnGroundItem(a, b) + if not id then return false end + local item = findItem(a) + if not item then return false end + + local dest = nil + for i, tile in ipairs(g_map.getTiles(posz())) do + for j, item in ipairs(tile:getItems()) do + if item:getId() == id then + dest = item + break + end + end + end + + if dest then + return useWith(item, dest) + else + return false + end +end + +-- returns target creature +function target() + if not g_game.isAttacking() then + return + else + return g_game.getAttackingCreature() + end +end + +-- returns target creature +function getTarget() return target() end + +-- dist is boolean +-- returns target position/distance from player +function targetPos(dist) + if not g_game.isAttacking() then return end + if dist then + return distanceFromPlayer(target():getPosition()) + else + return target():getPosition() + end +end + +-- for gunzodus/ezodus only +-- it will reopen loot bag, necessary for depositer +function reopenPurse() + for i, c in pairs(getContainers()) do + if c:getName():lower() == "loot bag" or c:getName():lower() == + "store inbox" then g_game.close(c) end + end + schedule(100, function() + g_game.use(g_game.getLocalPlayer():getInventoryItem(InventorySlotPurse)) + end) + schedule(1400, function() + for i, c in pairs(getContainers()) do + if c:getName():lower() == "store inbox" then + for _, i in pairs(c:getItems()) do + if i:getId() == 23721 then + g_game.open(i, c) + end + end + end + end + end) + return CaveBot.delay(1500) +end + +-- getSpectator patterns +-- param1 - pos/creature +-- param2 - pattern +-- param3 - type of return +-- 1 - everyone, 2 - monsters, 3 - players +-- returns number +function getCreaturesInArea(param1, param2, param3) + local specs = 0 + local monsters = 0 + local players = 0 + for i, spec in pairs(getSpectators(param1, param2)) do + if spec ~= player then + specs = specs + 1 + if spec:isMonster() and + (g_game.getClientVersion() < 960 or spec:getType() < 3) then + monsters = monsters + 1 + elseif spec:isPlayer() and not isFriend(spec:getName()) then + players = players + 1 + end + end + end + + if param3 == 1 then + return specs + elseif param3 == 2 then + return monsters + else + return players + end +end + +-- can be improved +-- TODO in future +-- uses getCreaturesInArea, specType +-- returns number +function getBestTileByPatern(pattern, specType, maxDist, safe) + if not pattern or not specType then return end + if not maxDist then maxDist = 4 end + + local bestTile = nil + local best = nil + for _, tile in pairs(g_map.getTiles(posz())) do + if distanceFromPlayer(tile:getPosition()) <= maxDist then + local minimapColor = g_map.getMinimapColor(tile:getPosition()) + local stairs = (minimapColor >= 210 and minimapColor <= 213) + if tile:canShoot() and tile:isWalkable() and not stairs then + if getCreaturesInArea(tile:getPosition(), pattern, specType) > 0 then + if (not safe or + getCreaturesInArea(tile:getPosition(), pattern, 3) == 0) then + local candidate = + { + pos = tile, + count = getCreaturesInArea(tile:getPosition(), + pattern, specType) + } + if not best or best.count <= candidate.count then + best = candidate + end + end + end + end + end + end + + bestTile = best + + if bestTile then + return bestTile + else + return false + end +end + +-- returns container object based on name +function getContainerByName(name) + if type(name) ~= "string" then return nil end + + local d = nil + for i, c in pairs(getContainers()) do + if c:getName():lower() == name:lower() then + d = c + break + end + end + return d +end + +-- returns container object based on container ID +function getContainerByItem(id) + if type(id) ~= "number" then return nil end + + local d = nil + for i, c in pairs(getContainers()) do + if c:getContainerItem():getId() == id then + d = c + break + end + end + return d +end + +-- [[ ready to use getSpectators patterns ]] -- + +LargeUeArea = [[ + 0000001000000 + 0000011100000 + 0000111110000 + 0001111111000 + 0011111111100 + 0111111111110 + 1111111111111 + 0111111111110 + 0011111111100 + 0001111111000 + 0000111110000 + 0000011100000 + 0000001000000 +]] + +NormalUeAreaMs = [[ + 00000100000 + 00011111000 + 00111111100 + 01111111110 + 01111111110 + 11111111111 + 01111111110 + 01111111110 + 00111111100 + 00001110000 + 00000100000 +]] + +NormalUeAreaEd = [[ + 00000100000 + 00001110000 + 00011111000 + 00111111100 + 01111111110 + 11111111111 + 01111111110 + 00111111100 + 00011111000 + 00001110000 + 00000100000 +]] + +smallUeArea = [[ + 0011100 + 0111110 + 1111111 + 1111111 + 1111111 + 0111110 + 0011100 +]] + +largeRuneArea = [[ + 0011100 + 0111110 + 1111111 + 1111111 + 1111111 + 0111110 + 0011100 +]] + +adjacentArea = [[ + 111 + 101 + 111 +]] + +longBeamArea = [[ + 0000000N0000000 + 0000000N0000000 + 0000000N0000000 + 0000000N0000000 + 0000000N0000000 + 0000000N0000000 + 0000000N0000000 + WWWWWWW0EEEEEEE + 0000000S0000000 + 0000000S0000000 + 0000000S0000000 + 0000000S0000000 + 0000000S0000000 + 0000000S0000000 + 0000000S0000000 +]] + +shortBeamArea = [[ + 00000100000 + 00000100000 + 00000100000 + 00000100000 + 00000100000 + EEEEE0WWWWW + 00000S00000 + 00000S00000 + 00000S00000 + 00000S00000 + 00000S00000 +]] + +newWaveArea = [[ + 000NNNNN000 + 000NNNNN000 + 0000NNN0000 + WW00NNN00EE + WWWW0N0EEEE + WWWWW0EEEEE + WWWW0S0EEEE + WW00SSS00EE + 0000SSS0000 + 000SSSSS000 + 000SSSSS000 +]] + +bigWaveArea = [[ + 0000NNN0000 + 0000NNN0000 + 0000NNN0000 + 00000N00000 + WWW00N00EEE + WWWWW0EEEEE + WWW00S00EEE + 00000S00000 + 0000SSS0000 + 0000SSS0000 + 0000SSS0000 +]] + +smallWaveArea = [[ + 00NNN00 + 00NNN00 + WW0N0EE + WWW0EEE + WW0S0EE + 00SSS00 + 00SSS00 +]] + +diamondArrowArea = [[ + 01110 + 11111 + 11111 + 11111 + 01110 +]] diff --git a/modules/game_bot/executor.lua b/modules/game_bot/executor.lua index 9c31882..7f423b3 100644 --- a/modules/game_bot/executor.lua +++ b/modules/game_bot/executor.lua @@ -64,7 +64,8 @@ function executeBot(config, storage, tabs, msgCallback, saveConfigCallback, relo onTurn = {}, onWalk = {}, onImbuementWindow = {}, - onModalDialog = {} + onModalDialog = {}, + onAttackingCreatureChange = {} } -- basic functions & classes @@ -355,6 +356,11 @@ function executeBot(config, storage, tabs, msgCallback, saveConfigCallback, relo callback(id, title, message, buttons, enterButton, escapeButton, choices, priority) end end, + onAttackingCreatureChange = function(creature, oldCreature) + for i, callback in ipairs(context._callbacks.onAttackingCreatureChange) do + callback(creature, oldCreature) + end + end, } } end \ No newline at end of file diff --git a/modules/game_bot/functions/callbacks.lua b/modules/game_bot/functions/callbacks.lua index 703016a..0ae973c 100644 --- a/modules/game_bot/functions/callbacks.lua +++ b/modules/game_bot/functions/callbacks.lua @@ -185,6 +185,11 @@ context.onModalDialog = function(callback) return context.callback("onModalDialog", callback) end +-- onAttackingCreatureChange -- callback = function(creature, oldCreature) +context.onAttackingCreatureChange = function(callback) + return context.callback("onAttackingCreatureChange", callback) +end + -- CUSTOM CALLBACKS -- listen(name, callback) -- callback = function(text, channelId, pos) diff --git a/modules/game_bot/functions/player.lua b/modules/game_bot/functions/player.lua index 3541280..baea6dc 100644 --- a/modules/game_bot/functions/player.lua +++ b/modules/game_bot/functions/player.lua @@ -124,7 +124,7 @@ context.usewith = function(thing, target, subtype) if type(thing) == 'number' then return g_game.useInventoryItemWith(thing, target, subtype) else - return g_game.useWith(item, target, subtype) + return g_game.useWith(thing, target, subtype) end end context.useWith = context.usewith diff --git a/modules/game_shop/shop.lua b/modules/game_shop/shop.lua index bce0046..3f7ca69 100644 --- a/modules/game_shop/shop.lua +++ b/modules/game_shop/shop.lua @@ -2,10 +2,12 @@ local SHOP_EXTENTED_OPCODE = 201 shop = nil +transferWindow = nil local otcv8shop = false local shopButton = nil local msgWindow = nil local browsingHistory = false +local transferValue = 0 -- for classic store local storeUrl = "" @@ -51,6 +53,8 @@ function init() if g_game.isOnline() then check() end + createShop() + createTransferWindow() end function terminate() @@ -107,6 +111,29 @@ function show() shop:focus() end +function softHide() + if not transferWindow then return end + + transferWindow:hide() + shop:show() +end + +function showTransfer() + if not shop or not transferWindow then return end + + hide() + transferWindow:show() + transferWindow:raise() + transferWindow:focus() +end + +function hideTransfer() + if not shop or not transferWindow then return end + + transferWindow:hide() + show() +end + function toggle() if not shop then return @@ -126,6 +153,11 @@ function createShop() connect(shop.categories, { onChildFocusChange = changeCategory }) end +function createTransferWindow() + if transferWindow then return end + transferWindow = g_ui.displayUI('transfer') + transferWindow:hide() +end function onStoreInit(url, coins) if otcv8shop then return end @@ -141,6 +173,7 @@ function onStoreInit(url, coins) end coinsPacketSize = coins createShop() + createTransferWindow() end function onStoreCategories(categories) @@ -228,23 +261,46 @@ end function onStorePurchase(message) if not shop or otcv8shop then return end - processMessage({title="Successful shop purchase", msg=message}) + if not transferWindow:isVisible() then + processMessage({title="Successful shop purchase", msg=message}) + else + processMessage({title="Successfuly gifted coins", msg=message}) + softHide() + end end function onStoreError(errorType, message) if not shop or otcv8shop then return end - processMessage({title="Shop error", msg=message}) + if not transferWindow:isVisible() then + processMessage({title="Shop Error", msg=message}) + else + processMessage({title="Gift coins error", msg=message}) + end end function onCoinBalance(coins, transferableCoins) if not shop or otcv8shop then return end shop.infoPanel.points:setText(tr("Points:") .. " " .. coins) + transferWindow.coinsBalance:setText(tr('Transferable Tibia Coins: ') .. coins) + transferWindow.coinsAmount:setMaximum(coins) shop.infoPanel.buy:hide() shop.infoPanel:setHeight(20) end +function transferCoins() + if not transferWindow then return end + local amount = 0 + amount = transferWindow.coinsAmount:getValue() + local recipient = transferWindow.recipient:getText() + + g_game.transferCoins(recipient, amount) + transferWindow.recipient:setText('') + transferWindow.coinsAmount:setValue(0) +end + function onExtendedJSONOpcode(protocol, code, json_data) createShop() + createTransferWindow() local action = json_data['action'] local data = json_data['data'] diff --git a/modules/game_shop/shop.otui b/modules/game_shop/shop.otui index 10c05f3..87f14e2 100644 --- a/modules/game_shop/shop.otui +++ b/modules/game_shop/shop.otui @@ -227,10 +227,19 @@ MainWindow anchors.bottom: parent.bottom @onClick: modules.game_shop.showHistory() + Button + id: transferOpen + !text: tr('Transfer Coins') + width: 128 + anchors.left: prev. right + margin-left: 10 + anchors.verticalCenter: prev.verticalCenter + @onClick: modules.game_shop.showTransfer() + Button id: buttonCancel !text: tr('Close') width: 64 anchors.right: parent.right anchors.bottom: parent.bottom - @onClick: modules.game_shop.hide() + @onClick: modules.game_shop.hide() \ No newline at end of file diff --git a/modules/game_shop/transfer.otui b/modules/game_shop/transfer.otui new file mode 100644 index 0000000..dbfefc4 --- /dev/null +++ b/modules/game_shop/transfer.otui @@ -0,0 +1,80 @@ +MainWindow + id: transferWindow + !text: tr('Gift Tibia Coins') + size: 280 240 + @onEscape: modules.game_shop.hideTransfer() + + Label + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + text-wrap: true + height: 56 + !text: tr('Please select the amount of Tibia Coins you would like to gift and enter the name of the character that should receive the Tibia Coins.') + + Label + anchors.top: prev.bottom + anchors.left: parent.left + margin-top: 20 + !text: tr('Reciepient:') + + TextEdit + id: recipient + anchors.verticalCenter: prev.verticalCenter + anchors.right: parent.right + width: 150 + text-align: left + + Label + id: coinsBalance + anchors.top: prev.bottom + anchors.left: parent.left + anchors.right: parent.right + margin-top: 10 + text-align: center + !text: tr('Transferable Tibia Coins:') + + Label + id: coinsAmountLabel + anchors.top: prev.bottom + anchors.left: parent.left + margin-top: 20 + !text: tr('Amount to gift: ') + + SpinBox + id: coinsAmount + anchors.right: parent.right + width: 100 + anchors.verticalCenter: prev.verticalCenter + text: 0 + minimum: 0 + maximum: 0 + focusable: true + editable: true + + HorizontalSeparator + anchors.right: parent.right + anchors.left: parent.left + anchors.bottom: cancelButton.top + margin-bottom: 8 + + Button + id: cancelButton + !text: tr('Cancel') + font: cipsoftFont + anchors.right: parent.right + anchors.bottom: parent.bottom + size: 45 21 + margin-top: 15 + margin-right: 5 + @onClick: modules.game_shop.hideTransfer() + + Button + id: giftButton + !text: tr('Gift') + font: cipsoftFont + size: 45 21 + anchors.verticalCenter: prev.verticalCenter + anchors.right: prev.left + margin-right: 5 + @onClick: modules.game_shop.transferCoins() \ No newline at end of file diff --git a/otclient_dx.exe b/otclient_dx.exe index d621d11..76433cd 100644 Binary files a/otclient_dx.exe and b/otclient_dx.exe differ diff --git a/otclient_gl.exe b/otclient_gl.exe index e73660b..415dbd5 100644 Binary files a/otclient_gl.exe and b/otclient_gl.exe differ diff --git a/otclientv8.apk b/otclientv8.apk index 879e5ae..1d4d315 100644 Binary files a/otclientv8.apk and b/otclientv8.apk differ