yeah rock5 was right back than.
Here is something new I use since a few months I was able to solve the bugs
I. If the distance between 2 waypoints is too short the bot stops now for changing the angle .
II. If the second waypoint is behind the first the bot stops now for changing the angle .
I was also able to solve any overcontrol probleme through less yrest times and using MM 1.03 beta 1.
I did change additional to that the way quickturn = false behave, It now simulate rotating the char with the camera like before it does but only to a point and then simulate a click in front of you. I tried to model it the way I play the game I also added some randomization to it so that it will also look a bit different each time, but that a only ably on when you are on foot, on a mount the bot will move like a car.
Code: Select all
function CPlayer:moveTo(waypoint, ignoreCycleTargets, dontStopAtEnd, range, zone)
if settings.profile.options.PARTYLEADER_WAIT and GetPartyMemberName(1) then
if not checkparty(150) then
releaseKeys()
repeat yrest(500) self:updateBattling() until checkparty(150) or self.Battling
end
end
if(zone == nil) then zone = 0; end;
local function passed_point(lastpos, point)
point.X = tonumber(point.X)
point.Z = tonumber(point.Z)
local posbuffer = 20 + zone;
local passed = true
if lastpos.X < point.X and self.X < point.X - posbuffer then
return false
end
if lastpos.X > point.X and self.X > point.X + posbuffer then
return false
end
if lastpos.Z < point.Z and self.Z < point.Z - posbuffer then
return false
end
if lastpos.Z > point.Z and self.Z > point.Z + posbuffer then
return false
end
return true
end
self:updateXYZ();
local angle = math.atan2(waypoint.Z - self.Z, waypoint.X - self.X);
local yangle = 0
if waypoint.Y ~= nil then
yangle = math.atan2(waypoint.Y - self.Y, ((waypoint.X - self.X)^2 + (waypoint.Z - self.Z)^2)^.5 );
end
self:updateDirection()
local angleDif = angleDifference(angle, self.Direction);
local startTime = os.time();
ignoreTargets = ignoreTargets or false;
if( ignoreCycleTargets == nil ) then
ignoreCycleTargets = false;
end;
local distNextWP = distance(self.X, self.Z, self.Y, waypoint.X, waypoint.Z, waypoint.Y);
if (settings.profile.options.WP_NO_STOP == true and player.Mounted and (distNextWP <= 80 or angleDif >= math.rad(135) )) then
if (dontStopAtEnd == true) then
keyboardRelease( settings.hotkeys.MOVE_FORWARD.key );
end
end
if( waypoint.Type == WPT_TRAVEL or waypoint.Type == WPT_RUN ) then
if( settings.profile.options.DEBUG_TARGET ) then
cprintf(cli.yellow, "[DEBUG] waypoint type RUN or TRAVEL. We don't target mobs.\n");
end
ignoreCycleTargets = true; -- don't target mobs
end;
-- Make sure we don't have a garbage (dead) target
self:updateTargetPtr()
if( self.TargetPtr ~= 0 ) then
local target = CPawn.new(self.TargetPtr)
if target:exists() then -- Target exists
target:updateHP()
if( target.HP <= 1 ) then
self:clearTarget();
end
end
end
-- no active turning and moving if wander and radius = 0
-- self direction has values from 0 til Pi and -Pi til 0
-- angle has values from 0 til 2*Pi
if(__WPL:getMode() == "wander" and
__WPL:getRadius() == 0 ) then
self:restrnd(100, 1, 4); -- wait 3 sec
self:updateDirection()
angle = self.Direction
-- we will not move back to WP if wander and radius = 0
-- so one can move the character manual and use the bot only as fight support
-- there we set the WP to the actual player position
self:updateXYZ()
waypoint.Z = self.Z;
waypoint.X = self.X;
end;
-- QUICK_TURN only
if( settings.profile.options.QUICK_TURN == true ) then
self:faceDirection(angle, yangle);
camera:setRotation(angle);
angleDif = angleDifference(angle, self.Direction);
else
self:faceDirection(self.Direction, yangle); -- change only 'Y' angle with 'faceDirection'.
end
if( settings.profile.options.QUICK_TURN == false and not player.Mounted) then
angleDif2 = angleDifference(angle, self.Direction);
if(angleDif2 < math.rad(65 + math.random(-5,5)) and angleDif2 > math.rad(15) ) then
self:faceDirection(angle, yangle);
camera:setRotation(angle);
self:updateDirection()
angleDif = angleDifference(angle, self.Direction);
end
end
-- If more than X degrees off, correct before moving.
local rotateStartTime = os.time();
local turningDir = -1; -- 0 = left, 1 = right
local randomAngle = math.rad(65 + math.random(-5,5));
while( angleDif > math.rad(65) ) do
self:updateHP()
self:updateAlive()
if( self.HP < 1 or self.Alive == false ) then
return false, WF_NONE;
end;
if( (angleDif < randomAngle and angleDif > math.rad(20)) and not player.Mounted ) then
self:faceDirection(angle, yangle);
camera:setRotation(angle);
end
if( os.difftime(os.time(), rotateStartTime) > 3.0 ) then
-- Sometimes both left and right rotate get stuck down.
-- Press them both to make sure they are fully released.
keyboardPress(settings.hotkeys.ROTATE_LEFT.key);
keyboardPress(settings.hotkeys.ROTATE_RIGHT.key);
-- we seem to have been distracted, take a step back.
keyboardPress(settings.hotkeys.MOVE_BACKWARD.key);
rotateStartTime = os.time();
end
if( angleDifference(angle, self.Direction + 0.01) < angleDif ) then
-- rotate left
keyboardRelease( settings.hotkeys.ROTATE_RIGHT.key );
keyboardHold( settings.hotkeys.ROTATE_LEFT.key );
--self:faceDirection( angle );
else
-- rotate right
keyboardRelease( settings.hotkeys.ROTATE_LEFT.key );
keyboardHold( settings.hotkeys.ROTATE_RIGHT.key );
--self:faceDirection( angle );
end
yrest(50);
self:updateDirection();
angleDif = angleDifference(angle, self.Direction);
end
keyboardRelease( settings.hotkeys.ROTATE_LEFT.key );
keyboardRelease( settings.hotkeys.ROTATE_RIGHT.key );
self:updateXYZ()
-- look for a target before start movig
self:updateBattling()
if((not self.Fighting) and (not ignoreCycleTargets)) then
if self:target(self:findEnemy(false, nil, evalTargetDefault, self.IgnoreTarget)) then -- find a new target
cprintf(cli.turquoise, language[86]); -- stopping waypoint::target acquired before moving
success = false;
failreason = WF_TARGET;
return success, failreason;
end;
end;
-- Direction ok, start moving forward
local success, failreason = true, WF_NONE;
local dist = distance(self.X, self.Z, self.Y, waypoint.X, waypoint.Z, waypoint.Y);
local lastDist = dist;
local lastpos = {X=self.X, Z=self.Z, Y=self.Y}
self.LastDistImprove = os.time(); -- global, because we reset it whil skill use
local turning = false
local loopstart
local loopduration = 100 -- The duration we want the loop to take
local successdist = 10
repeat
player:checkAddress()
loopstart = os.time()
dist = distance(self.X, self.Z, self.Y, waypoint.X, waypoint.Z, waypoint.Y);
angle = math.atan2(waypoint.Z - self.Z, waypoint.X - self.X);
self:updateHP()
self:updateAlive()
if( self.HP < 1 or self.Alive == false ) then
return false, WF_NONE;
end;
-- stop moving if aggro, bot will stand and wait until to get the target from the client
-- only if not in the fight stuff coding (means self.Fighting == false )
self:updateBattling()
self:updateXYZ()
if( self.Battling and -- we have aggro
self.Fighting == false and -- we are not coming from the fight routines (bec. as melee we should move in fight)
waypoint.Type ~= WPT_TRAVEL ) then -- only stop if not waypoint type TRAVEL
if self:target(self:findEnemy(true, nil, evalTargetDefault)) then
keyboardRelease( settings.hotkeys.MOVE_FORWARD.key );
keyboardRelease( settings.hotkeys.ROTATE_LEFT.key );
keyboardRelease( settings.hotkeys.ROTATE_RIGHT.key );
success = false;
failreason = WF_COMBAT;
break;
end
end;
self:updateXYZ()
-- look for a new target while moving
if((not ignoreCycleTargets) and (not self.Fighting)) then
if self:target(self:findEnemy(false, nil, evalTargetDefault, self.IgnoreTarget)) then
cprintf(cli.turquoise, language[28]); -- stopping waypoint::target acquired
success = false;
failreason = WF_TARGET;
break;
end;
end
-- We're still making progress
if( dist < lastDist ) then
self.LastDistImprove = os.time();
lastDist = dist;
lastpos = {X=self.X, Z=self.Z, Y=self.Y}
elseif( dist > lastDist + 40 ) then
-- Check if pulled back before last waypoint
local lastwp = __WPL:getNextWaypoint(-1)
if (lastwp.X ~= 0 or lastwp.Z ~= 0 or lastwp.Y ~= nil) and distance(player, lastpos) > distance(lastwp, lastpos) then
print("Was pulled back. Reseting waypoint.")
success = false
failreason = WF_PULLBACK
else
-- Make sure we didn't pass it up
printf(language[29]);
success = false;
failreason = WF_DIST;
end
break;
end;
if( os.difftime(os.time(), self.LastDistImprove) > 3 ) then
-- We haven't improved for 3 seconds, assume stuck
success = false;
failreason = WF_STUCK;
break;
end
-- while moving without target: check potions / friendly skills
self:updateMounted()
if not self.Mounted and ( self:checkPotions() or self:checkSkills(ONLY_FRIENDLY) ) then -- only cast friendly spells to ourselfe
-- If we used a potion or a skill, reset our last dist improvement
-- to prevent unsticking
self.LastDistImprove = os.time();
-- Wait for casting to finish if still casting last skill
self:updateCasting()
while self.Casting do
yrest(50)
self:updateCasting()
end
end
-- Check if within range if range specified
if range and range > dist then
-- within range
break
end
-- Check if past waypoint
if passed_point(lastpos, waypoint) then
-- waypoint reached
break
end
-- Check if close to waypoint.
if dist < successdist then
break
end
if waypoint.Y ~= nil then
yangle = math.atan2(waypoint.Y - self.Y, ((waypoint.X - self.X)^2 + (waypoint.Z - self.Z)^2)^.5 );
end
self:updateDirection()
angleDif = angleDifference(angle, self.Direction);
yrest(1) -- This is to fix a bug that causes the bot to continue moving forward after it has been paused.
-- Continue to make sure we're facing the right direction
if( settings.profile.options.QUICK_TURN and angleDif > math.rad(1) ) then
self:updateDirection()
angle = math.atan2(waypoint.Z - self.Z, waypoint.X - self.X);
self:faceDirection(angle, yangle);
camera:setRotation(angle);
angleDif = angleDifference(angle, self.Direction);
keyboardHold( settings.hotkeys.MOVE_FORWARD.key );
else
self:faceDirection(self.Direction, yangle); -- change only 'Y' angle with 'faceDirection'.
if( (angleDif < randomAngle and angleDif > math.rad(20)) and not player.Mounted ) then
camera:setRotation(angle);
self:faceDirection(angle, yangle);
end
self:updateDirection()
angle = math.atan2(waypoint.Z - self.Z, waypoint.X - self.X);
angleDif = angleDifference(angle, self.Direction);
if( angleDif > math.rad(15) ) then
--keyboardRelease( settings.hotkeys.MOVE_FORWARD.key );
--keyboardRelease( settings.hotkeys.MOVE_BACKWARD.key );
if( angleDifference(angle, self.Direction + 0.01) < angleDif ) then
keyboardRelease( settings.hotkeys.ROTATE_RIGHT.key );
keyboardHold( settings.hotkeys.ROTATE_LEFT.key );
yrest(50);
else
keyboardRelease( settings.hotkeys.ROTATE_LEFT.key );
keyboardHold( settings.hotkeys.ROTATE_RIGHT.key );
yrest(50);
end
turning = true
elseif( angleDif > math.rad(1) ) then
if( settings.profile.options.QUICK_TURN ) then
camera:setRotation(angle);
end
self:faceDirection(angle, yangle);
keyboardRelease( settings.hotkeys.ROTATE_LEFT.key );
keyboardRelease( settings.hotkeys.ROTATE_RIGHT.key );
keyboardHold( settings.hotkeys.MOVE_FORWARD.key );
turning = false
else
keyboardHold( settings.hotkeys.MOVE_FORWARD.key );
end
end
--keyboardHold( settings.hotkeys.MOVE_FORWARD.key );
local pausetime = loopduration - (os.time() - loopstart) -- minus the time already elapsed.
if pausetime < 1 then pausetime = 1 end
yrest(pausetime);
self:updateXYZ()
waypoint:update();
until false
--cprintf(cli.green,"We are in moveTo \n ");
if (settings.profile.options.WP_NO_STOP ~= false) then
--cprintf(cli.green,"WP_NO_STOP = true \n ");
if (dontStopAtEnd ~= true) --[[or (settings.profile.options.QUICK_TURN == false)]] then
keyboardRelease( settings.hotkeys.MOVE_FORWARD.key );
end
else
--cprintf(cli.green,"WP_NO_STOP = false \n ");
keyboardRelease( settings.hotkeys.MOVE_FORWARD.key );
end
keyboardRelease( settings.hotkeys.ROTATE_LEFT.key );
keyboardRelease( settings.hotkeys.ROTATE_RIGHT.key );
return success, failreason;
end
Their is/was also a drop out/drop in of the mode when stuck in bot.lua, it will/would take some time until I made a integration in the common romBot but perhaps rock find some time since all problems are solved this time.