mirror of
https://github.com/OTCv8/otclientv8.git
synced 2025-10-23 07:55:55 +02:00
Updated to OTCv8 3.0 rev 19
This commit is contained in:
889
modules/game_bot/default_configs/vBot/__vlib.lua
Normal file
889
modules/game_bot/default_configs/vBot/__vlib.lua
Normal file
@@ -0,0 +1,889 @@
|
||||
-- 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
|
||||
]]
|
Reference in New Issue
Block a user