mirror of
https://github.com/OTCv8/otclientv8.git
synced 2025-05-06 05:49:20 +02:00
182 lines
6.8 KiB
Lua
182 lines
6.8 KiB
Lua
TargetBot.Creature.attack = function(params, targets, isLooting) -- params {config, creature, danger, priority}
|
|
if player:isWalking() then
|
|
lastWalk = now
|
|
end
|
|
|
|
local config = params.config
|
|
local creature = params.creature
|
|
|
|
if g_game.getAttackingCreature() ~= creature then
|
|
g_game.attack(creature)
|
|
end
|
|
|
|
if not isLooting then -- walk only when not looting
|
|
TargetBot.Creature.walk(creature, config, targets)
|
|
end
|
|
|
|
-- attacks
|
|
local mana = player:getMana()
|
|
if config.useGroupAttack and config.groupAttackSpell:len() > 1 and mana > config.minManaGroup then
|
|
local creatures = g_map.getSpectatorsInRange(player:getPosition(), false, config.groupAttackRadius, config.groupAttackRadius)
|
|
local playersAround = false
|
|
local monsters = 0
|
|
for _, creature in ipairs(creatures) do
|
|
if not creature:isLocalPlayer() and creature:isPlayer() and (not config.groupAttackIgnoreParty or creature:getShield() <= 2) then
|
|
playersAround = true
|
|
elseif creature:isMonster() then
|
|
monsters = monsters + 1
|
|
end
|
|
end
|
|
if monsters >= config.groupAttackTargets and (not playersAround or config.groupAttackIgnorePlayers) then
|
|
if TargetBot.sayAttackSpell(config.groupAttackSpell, config.groupAttackDelay) then
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
if config.useGroupAttackRune and config.groupAttackRune > 100 then
|
|
local creatures = g_map.getSpectatorsInRange(creature:getPosition(), false, config.groupRuneAttackRadius, config.groupRuneAttackRadius)
|
|
local playersAround = false
|
|
local monsters = 0
|
|
for _, creature in ipairs(creatures) do
|
|
if not creature:isLocalPlayer() and creature:isPlayer() and (not config.groupAttackIgnoreParty or creature:getShield() <= 2) then
|
|
playersAround = true
|
|
elseif creature:isMonster() then
|
|
monsters = monsters + 1
|
|
end
|
|
end
|
|
if monsters >= config.groupRuneAttackTargets and (not playersAround or config.groupAttackIgnorePlayers) then
|
|
if TargetBot.useAttackItem(config.groupAttackRune, 0, creature, config.groupRuneAttackDelay) then
|
|
return
|
|
end
|
|
end
|
|
end
|
|
if config.useSpellAttack and config.attackSpell:len() > 1 and mana > config.minMana then
|
|
if TargetBot.sayAttackSpell(config.attackSpell, config.attackSpellDelay) then
|
|
return
|
|
end
|
|
end
|
|
if config.useRuneAttack and config.attackRune > 100 then
|
|
if TargetBot.useAttackItem(config.attackRune, 0, creature, config.attackRuneDelay) then
|
|
return
|
|
end
|
|
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()
|
|
|
|
local isTrapped = true
|
|
local pos = player:getPosition()
|
|
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 and tile:isWalkable(false) then
|
|
isTrapped = false
|
|
end
|
|
end
|
|
|
|
-- data for external dynamic lure
|
|
if config.lureMin and config.lureMax then
|
|
if config.lureMin >= targets then
|
|
storage.TargetBotLure = true
|
|
elseif targets >= config.lureMax then
|
|
storage.TargetBotLure = false
|
|
end
|
|
end
|
|
storage.targetBotTargets = targets
|
|
storage.targetBotDynamicLureDelayValue = config.lureDelay
|
|
|
|
if not storage.targetBotLureMax then
|
|
storage.targetBotLureMax = 0
|
|
end
|
|
if config.lureMax then
|
|
storage.targetBotLureMax = 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
|
|
return TargetBot.allowCaveBot(150)
|
|
else
|
|
if targets < config.lureCount then
|
|
if config.lureCavebot then
|
|
return TargetBot.allowCaveBot(150)
|
|
else
|
|
local path = findPath(pos, cpos, 5, {ignoreNonPathable=true, precision=2})
|
|
if path then
|
|
return TargetBot.walkTo(cpos, 10, {marginMin=5, marginMax=6, ignoreNonPathable=true})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local currentDistance = findPath(pos, cpos, 10, {ignoreCreatures=true, ignoreNonPathable=true, ignoreCost=true})
|
|
if config.chase and (creature:getHealthPercent() < 30 or not config.keepDistance) then
|
|
if #currentDistance > 1 then
|
|
return TargetBot.walkTo(cpos, 10, {ignoreNonPathable=true, precision=1})
|
|
end
|
|
elseif config.keepDistance then
|
|
if #currentDistance ~= config.keepDistanceRange and #currentDistance ~= config.keepDistanceRange + 1 then
|
|
return TargetBot.walkTo(cpos, 10, {ignoreNonPathable=true, marginMin=config.keepDistanceRange, marginMax=config.keepDistanceRange + 1})
|
|
end
|
|
end
|
|
|
|
if config.avoidAttacks then
|
|
local diffx = cpos.x - pos.x
|
|
local diffy = cpos.y - pos.y
|
|
local candidates = {}
|
|
if math.abs(diffx) == 1 and diffy == 0 then
|
|
candidates = {{x=pos.x, y=pos.y-1, z=pos.z}, {x=pos.x, y=pos.y+1, z=pos.z}}
|
|
elseif diffx == 0 and math.abs(diffy) == 1 then
|
|
candidates = {{x=pos.x-1, y=pos.y, z=pos.z}, {x=pos.x+1, y=pos.y, z=pos.z}}
|
|
end
|
|
for _, candidate in ipairs(candidates) do
|
|
local tile = g_map.getTile(candidate)
|
|
if tile and tile:isWalkable() then
|
|
return TargetBot.walkTo(candidate, 2, {ignoreNonPathable=true})
|
|
end
|
|
end
|
|
elseif config.faceMonster then
|
|
local diffx = cpos.x - pos.x
|
|
local diffy = cpos.y - pos.y
|
|
local candidates = {}
|
|
if diffx == 1 and diffy == 1 then
|
|
candidates = {{x=pos.x+1, y=pos.y, z=pos.z}, {x=pos.x, y=pos.y-1, z=pos.z}}
|
|
elseif diffx == -1 and diffy == 1 then
|
|
candidates = {{x=pos.x-1, y=pos.y, z=pos.z}, {x=pos.x, y=pos.y-1, z=pos.z}}
|
|
elseif diffx == -1 and diffy == -1 then
|
|
candidates = {{x=pos.x, y=pos.y-1, z=pos.z}, {x=pos.x-1, y=pos.y, z=pos.z}}
|
|
elseif diffx == 1 and diffy == -1 then
|
|
candidates = {{x=pos.x, y=pos.y-1, z=pos.z}, {x=pos.x+1, y=pos.y, z=pos.z}}
|
|
else
|
|
local dir = player:getDirection()
|
|
if diffx == 1 and dir ~= 1 then turn(1)
|
|
elseif diffx == -1 and dir ~= 3 then turn(3)
|
|
elseif diffy == 1 and dir ~= 2 then turn(2)
|
|
elseif diffy == -1 and dir ~= 0 then turn(0)
|
|
end
|
|
end
|
|
for _, candidate in ipairs(candidates) do
|
|
local tile = g_map.getTile(candidate)
|
|
if tile and tile:isWalkable() then
|
|
return TargetBot.walkTo(candidate, 2, {ignoreNonPathable=true})
|
|
end
|
|
end
|
|
end
|
|
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
|
|
|
|
CaveBot.delay(storage.targetBotDynamicLureDelayValue or 0)
|
|
end) |