Thanks man,i'v got xp in fucking around with programs and getting em to work,this is pure code though,and i suck at code.d003232 wrote:You are a good tester ... with your profile
Just make a little correction at your seetings.lua line 345/346I should be '_name' instead of 'name'. It will be in the SVN after I have the other stuff finished.Code: Select all
local err = sprintf("Profile error: Please set a valid key for ".. "hotkey %s in your profile file \'%s.xml\'.", tostring(v:getAttribute("name")), _name );
Bad argument #1 to getkeyname
Re: Bad argument #1 to getkeyname
Re: Bad argument #1 to getkeyname
The SVN 196 is now commited. It should now correct check your profile and show you the error without having an error.Suffering wrote:Thanks man,i'v got xp in fucking around with programs and getting em to work,this is pure code though,and i suck at code.
The RoM Bot Online Wiki needs your help!
Re: Bad argument #1 to getkeyname
Thanks for all your help so far,but im still getting problems.This time its:
player.lua:748 bad argument #1 to 'keyboardrelease' <<null>>
my player.lua:
player.lua:748 bad argument #1 to 'keyboardrelease' <<null>>
my player.lua:
Code: Select all
include("pawn.lua");
include("skill.lua");
WF_NONE = 0; -- We didn't fail
WF_TARGET = 1; -- Failed waypoint because we have a target
WF_DIST = 2; -- Broke because our distance somehow increased. It happens.
WF_STUCK = 3; -- Failed waypoint because we are stuck on something.
WF_COMBAT = 4; -- stopped waypoint because we are in combat
ONLY_FRIENDLY = true; -- only cast friendly spells HEAL / HOT / BUFF
JUMP_FALSE = false -- dont jump to break cast
JUMP_TRUE = true -- jump to break cast
CPlayer = class(CPawn);
function CPlayer:harvest( _second_try )
if( foregroundWindow() ~= getWin() ) then
return;
end
local function scan()
local mousePawn;
-- Screen dimension variables
local wx, wy, ww, wh = windowRect(getWin());
local halfWidth = ww/2;
local halfHeight = wh/2;
-- Scan rect variables
local scanWidth = settings.profile.options.HARVEST_SCAN_WIDTH; -- Width, in 'steps', of the area to scan
local scanHeight = settings.profile.options.HARVEST_SCAN_HEIGHT; -- Height, in 'steps', of area to scan
local scanXMultiplier = settings.profile.options.HARVEST_SCAN_XMULTIPLIER; -- multiplier for scan width
local scanYMultiplier = settings.profile.options.HARVEST_SCAN_YMULTIPLIER; -- multiplier for scan line height
local scanStepSize = settings.profile.options.HARVEST_SCAN_STEPSIZE; -- Distance, in pixels, between 'steps'
local mx, my; -- Mouse x/y temp values
mouseSet(wx + (halfWidth*scanXMultiplier - (scanWidth/2*scanStepSize)),
wy + (halfHeight*scanYMultiplier - (scanHeight/2*scanStepSize)));
yrest(100);
local scanstart, scanende, scanstep;
-- define scan direction top/down or bottom/up
if( settings.profile.options.HARVEST_SCAN_TOPDOWN == true ) then
scanstart = 0;
scanende = scanHeight-1;
scanstep = 1;
else
scanstart = scanHeight;
scanende = 0;
scanstep = -1;
end;
-- Scan nearby area for a node
keyboardHold(key.VK_SHIFT); -- press shift so you can scan trough players
for y = scanstart, scanende, scanstep do
my = math.ceil(halfHeight * scanYMultiplier - (scanHeight / 2 * scanStepSize) + ( y * scanStepSize ));
for x = 0,scanWidth-1 do
mx = math.ceil(halfWidth * scanXMultiplier - (scanWidth / 2 * scanStepSize) + ( x * scanStepSize ));
mouseSet(wx + mx, wy + my);
yrest(settings.profile.options.HARVEST_SCAN_YREST);
mousePawn = CPawn(memoryReadIntPtr(getProc(), staticcharbase_address, mousePtr_offset));
if( mousePawn.Address ~= 0 and mousePawn.Type == PT_NODE
and distance(self.X, self.Z, mousePawn.X, mousePawn.Z) < 150
and database.nodes[mousePawn.Id] ) then
return mousePawn.Address, mx, my;
end
end
end
keyboardRelease(key.VK_SHIFT);
return 0, nil, nil;
end
detach(); -- Remove attach bindings
local mouseOrigX, mouseOrigY = mouseGetPos();
local foundHarvestNode, nodeMouseX, nodeMouseY = scan();
local hf_found = false;
local startHarvestTime = os.time();
if( foundHarvestNode ~= 0 and nodeMouseX and nodeMouseY ) then
-- We found something. Lets harvest it.
hf_found = true;
-- If out of distance, move and rescan
local mousePawn = CPawn(foundHarvestNode);
local dist = distance(self.X, self.Z, mousePawn.X, mousePawn.Z)
if( dist > 35 and dist < 150 ) then
printf(language[80]); -- Move in
self:moveTo( CWaypoint(mousePawn.X, mousePawn.Z), true );
yrest(200);
foundHarvestNode, nodeMouseX, nodeMouseY = scan();
end
while( foundHarvestNode ~= 0 and nodeMouseX and nodeMouseY ) do
self:update();
if( self.Battling ) then -- we get aggro, stop harversting
if( self.Returning ) then -- set wp one back to harverst wp
__RPL:backward(); -- again after the fight
else
__WPL:backward();
end;
break;
end;
if( os.difftime(os.time(), startHarvestTime) > 45 ) then
break;
end
local wx,wy = windowRect(getWin());
--mouseSet(wx + nodeMouseX, wy + nodeMouseY);
mouseSet(wx + nodeMouseX, wy + nodeMouseY);
yrest(50);
mousePawn = CPawn(memoryReadIntPtr(getProc(), staticcharbase_address, mousePtr_offset));
yrest(50);
if( mousePawn.Address ~= 0 and mousePawn.Type == PT_NODE
and database.nodes[mousePawn.Id] ~= nil ) then
-- Node is still here
-- Begin gathering
keyboardHold(key.VK_SHIFT);
mouseLClick();
yrest(100);
mouseLClick();
keyboardRelease(key.VK_SHIFT);
-- Wait for a few seconds... constantly check for aggro
local startWaitTime = os.time();
while( os.difftime(os.time(), startWaitTime) < 2 ) do
yrest(100);
self:update();
-- Make sure it didn't disapear
mousePawn = CPawn(memoryReadIntPtr(getProc(), staticcharbase_address, mousePtr_offset));
if( mousePawn.Address == 0 ) then
break;
end;
if( self.Battling ) then
break;
end
end
self:update();
else
-- Node is gone
break;
end
end
end
mouseSet(mouseOrigX, mouseOrigY);
attach(getWin()); -- Re-attach bindings
-- sometimes harvesting breaks at begin after found, because camera is still
-- moving, in that case, wait a little and harvest again
if( hf_found == true and
not _second_try and -- only one extra harverst try
os.difftime(os.time(), startHarvestTime) < 5 ) then
yrest(2000);
cprintf(cli.green, language[81]); -- Unexpected interruption at harvesting begin
player:harvest( true );
end
end
function CPlayer:initialize()
memoryWriteInt(getProc(), self.Address + castbar_offset, 0);
end
-- Resets "toggled" skills to off & used counter to 0
function CPlayer:resetSkills()
for i,v in pairs(settings.profile.skills) do
if( v.Toggled ) then
v.Toggled = false;
end
if( v.used ) then
v.used = 0;
end
end
end
-- Check if you can use any skills, and use them
-- if they are needed.
function CPlayer:checkSkills(_only_friendly)
for i,v in pairs(settings.profile.skills) do
if( v:canUse(_only_friendly) ) then
if( v.CastTime > 0 ) then
keyboardRelease( settings.hotkeys.MOVE_FORWARD.key );
yrest(200); -- Wait to stop only if not an instant cast spell
end
-- Make sure we aren't already busy casting something else
while(self.Casting) do
-- Waiting for casting to finish...
yrest(100);
self:update();
end
-- break cast if aggro before casting
if( self:check_aggro_before_cast(JUMP_FALSE) and
( v.Type == STYPE_DAMAGE or
v.Type == STYPE_DOT ) ) then -- without jump
return;
end;
v:use();
yrest(100);
self:update();
printf(language[21], getKeyName(v.hotkey), string.sub(v.Name.." ", 1, 20)); -- first part of 'casting ...'
-- Wait for casting to start (if it has a decent cast time)
if( v.CastTime > 0 ) then
local startTime = os.time();
while( not self.Casting ) do
-- break cast with jump if aggro before casting finished
if( self:check_aggro_before_cast(JUMP_TRUE) and
( v.Type == STYPE_DAMAGE or
v.Type == STYPE_DOT ) ) then -- with jump
printf(language[82]); -- close print 'Casting ..." / aborted
return;
end;
yrest(50);
self:update();
if( os.difftime(os.time(), startTime) > v.CastTime ) then
self.Casting = true; -- force it.
break;
end
end;
while(self.Casting) do
-- break cast with jump if aggro before casting finished
if( self:check_aggro_before_cast(JUMP_TRUE) and
( v.Type == STYPE_DAMAGE or
v.Type == STYPE_DOT ) ) then -- with jump
printf(language[82]); -- close print 'Casting ..."
return;
end;
-- Waiting for casting to finish...
yrest(10);
self:update();
end
-- printf(language[20]); -- finished casting
else
yrest(500); -- assume 0.5 second yrest
end
-- count cast to enemy targets
if( v.Target == 0 ) then -- target is unfriendly
self.Cast_to_target = self.Cast_to_target + 1;
end;
if( v.CastTime == 0 ) then
yrest(500);
else
yrest(100);
end;
-- print HP of our target
-- we do it later, because the client needs some time to change the values
local target = player:getTarget();
printf("=> "..target.Name.." ("..target.HP.."/"..target.MaxHP..")\n"); -- second part of 'casting ...'
-- the check was only done after every complete skill round
-- hence the message is not really needed anymore
-- we move the check INTO the skill round to be more accurate
-- by the max_fight_time option could be reduced
if( target.HP ~= lastTargetHP ) then
self.lastHitTime = os.time();
lastTargetHP = target.HP;
-- printf(language[23]); -- target HP changed
end
end
end
end
-- Check if you need to use any potions, and use them.
function CPlayer:checkPotions()
-- Still cooling down, don't use.
if( os.difftime(os.time(), self.PotionLastUseTime) < settings.profile.options.POTION_COOLDOWN+1 ) then
return;
end
-- If we need to use a health potion
if( (self.HP/self.MaxHP*100) < settings.profile.options.HP_LOW_POTION ) then
local modifier = settings.profile.hotkeys.HP_POTION.modifier
if( modifier ) then keyboardHold(modifier); end
keyboardPress(settings.profile.hotkeys.HP_POTION.key);
if( modifier ) then keyboardRelease(modifier); end
self.PotionLastUseTime = os.time();
cprintf(cli.green, language[10], getKeyName(settings.profile.hotkeys.HP_POTION.key) ); -- Using HP potion
if( self.Fighting ) then
yrest(1000);
end
end
-- If we need to use a mana potion(if we even have mana)
if( self.MaxMana > 0 ) then
if( (self.Mana/self.MaxMana*100) < settings.profile.options.MP_LOW_POTION ) then
local modifier = settings.profile.hotkeys.MP_POTION.modifier
if( modifier ) then keyboardHold(modifier); end
keyboardPress(settings.profile.hotkeys.MP_POTION.key);
if( modifier ) then keyboardRelease(modifier); end
self.PotionLastUseTime = os.time();
cprintf(cli.green, language[11], getKeyName(settings.profile.hotkeys.MP_POTION.key));
if( self.Fighting ) then
yrest(1000);
end
end
end
end
function CPlayer:fight()
self:update();
if( not self:haveTarget() ) then
return false;
end
local target = self:getTarget();
self.Fighting = true;
cprintf(cli.green, language[22], target.Name); -- engagin x in combat
-- Keep tapping the attack button once every few seconds
-- just in case the first one didn't go through
local function timedAttack()
self:update();
if( self.Casting ) then
-- Don't interupt casting
return;
end;
-- Prevents looting when looting is turned off
-- (target is dead, or about to be dead)
if( self.Target ~= 0 ) then
local target = self:getTarget();
if( (target.HP/target.MaxHP) <= 0.1 ) then
return;
end
end;
if( settings.profile.hotkeys.ATTACK.modifier ) then
keyboardHold(settings.hotkeys.ATTACK.modifier);
end
keyboardPress(settings.profile.hotkeys.ATTACK.key);
if( settings.profile.hotkeys.ATTACK.modifier ) then
keyboardRelease(settings.profile.hotkeys.ATTACK.modifier);
end
end
-- Prep for battle, if needed.
--self:checkSkills();
local target = self:getTarget();
self.lastHitTime = os.time();
local lastTargetHP = target.HP;
local move_closer_counter = 0; -- count move closer trys
self.Cast_to_target = 0; -- reset counter cast at enemy target
self.ranged_pull = false; -- flag for timed ranged pull for melees
local hf_start_dist = 0; -- distance to mob where we start the fight
-- check if timed ranged pull for melee
if(settings.profile.options.COMBAT_TYPE == "melee" and
settings.profile.options.COMBAT_RANGED_PULL == true and
self.Battling ~= true ) then
self.ranged_pull = true;
cprintf(cli.green, "We begin fight with ranged pulling.\n"); -- we start with ranged pulling
end
-- normal melee attack only if ranged pull isn't used
if( settings.profile.options.COMBAT_TYPE == "melee" and
self.ranged_pull ~= true ) then
registerTimer("timedAttack", secondsToTimer(2), timedAttack);
-- start melee attack (even if out of range)
timedAttack();
end
while( self:haveTarget() ) do
-- If we die, break
if( self.HP < 1 or self.Alive == false ) then
if( settings.profile.options.COMBAT_TYPE == "melee" ) then
unregisterTimer("timedAttack");
end
self.Fighting = false;
return;
end;
target = self:getTarget();
-- Exceeded max fight time (without hurting enemy) so break fighting
if( os.difftime(os.time(), self.lastHitTime) > settings.profile.options.MAX_FIGHT_TIME ) then
printf(language[83]); -- Taking too long to damage target
player.Last_ignore_target_ptr = player.TargetPtr; -- remember break target
player.Last_ignore_target_time = os.time(); -- and the time we break the fight
self:clearTarget();
break;
end
local dist = distance(self.X, self.Z, target.X, target.Z);
if( hf_start_dist == 0 ) then -- remember distance we start the fight
hf_start_dist = dist;
end
-- check if pulling phase should be finished
if( self.ranged_pull == true ) then
if( dist <= settings.options.MELEE_DISTANCE ) then
cprintf(cli.green, "Ranged pulling finished, mob in melee distance.\n");
self.ranged_pull = false;
elseif( os.difftime(os.time(), self.aggro_start_time) > 3 and
self.aggro_start_time ~= 0 ) then
cprintf(cli.green, "Ranged pulling after 3 sec wait finished.\n");
self.ranged_pull = false;
elseif( dist >= hf_start_dist-45 and -- mob not really coming closer
os.difftime(os.time(), self.aggro_start_time) > 1 and
self.aggro_start_time ~= 0 ) then
cprintf(cli.green, "Ranged pulling finished. Mob not really moving.\n");
self.ranged_pull = false;
end;
end
-- We're a bit TOO close...
if( dist < 5.0 ) then
printf(language[24]);
keyboardHold( settings.hotkeys.MOVE_BACKWARD.key);
yrest(200);
keyboardRelease( settings.hotkeys.MOVE_BACKWARD.key);
self:update();
dist = distance(self.X, self.Z, target.X, target.Z);
end
-- Move closer to the target if needed
local suggestedRange = settings.options.MELEE_DISTANCE;
if( suggestedRange == nil ) then suggestedRange = 45; end;
if( settings.profile.options.COMBAT_TYPE == "ranged" or
self.ranged_pull == true ) then
if( settings.profile.options.COMBAT_DISTANCE ~= nil ) then
suggestedRange = settings.profile.options.COMBAT_DISTANCE;
else
suggestedRange = 155;
end
end
if( dist > suggestedRange ) then
-- count move closer and break if to much
move_closer_counter = move_closer_counter + 1; -- count our move tries
if( move_closer_counter > 3 and
(settings.profile.options.COMBAT_TYPE == "ranged" or
self.ranged_pull == true) ) then
cprintf(cli.green, language[84]); -- To much tries to come closer
self:clearTarget();
break;
end
printf(language[25], suggestedRange, dist);
-- move into distance
local angle = math.atan2(target.Z - self.Z, target.X - self.X);
local posX, posZ;
local success, reason;
if( settings.profile.options.COMBAT_TYPE == "ranged" or
self.ranged_pull == true ) then -- melees with timed ranged pull
-- Move closer in increments
local movedist = dist/10; if( dist < 50 ) then movedist = dist - 5; end;
if( dist > 50 and movedist < 50 ) then movedist = 50 end;
posX = self.X + math.cos(angle) * (movedist);
posZ = self.Z + math.sin(angle) * (movedist);
success, reason = player:moveTo(CWaypoint(posX, posZ), true);
else -- normal melee
-- elseif( settings.profile.options.COMBAT_TYPE == "melee" ) then
success, reason = player:moveTo(target, true);
-- Start melee attacking
if( settings.profile.options.COMBAT_TYPE == "melee" ) then
timedAttack();
end
end
if( not success ) then
player:unstick();
end
yrest(500);
end
if( settings.profile.options.QUICK_TURN ) then
local angle = math.atan2(target.Z - self.Z, target.X - self.X);
self:faceDirection(angle);
camera:setRotation(angle);
elseif( settings.options.ENABLE_FIGHT_SLOW_TURN ) then
-- Make sure we're facing the enemy
local angle = math.atan2(target.Z - self.Z, target.X - self.X);
local angleDif = angleDifference(angle, self.Direction);
local correctingAngle = false;
local startTime = os.time();
while( angleDif > math.rad(15) ) do
if( self.HP < 1 or self.Alive == false ) then
return;
end;
if( os.difftime(os.time(), startTime) > 5 ) then
printf(language[26]);
break;
end;
correctingAngle = true;
if( angleDifference(angle, self.Direction + 0.01) < angleDif ) then
-- rotate left
keyboardRelease( settings.hotkeys.ROTATE_RIGHT.key );
keyboardHold( settings.hotkeys.ROTATE_LEFT.key );
else
-- rotate right
keyboardRelease( settings.hotkeys.ROTATE_LEFT.key );
keyboardHold( settings.hotkeys.ROTATE_RIGHT.key );
end
yrest(100);
self:update();
target:update();
angle = math.atan2(target.Z - self.Z, target.X - self.X);
angleDif = angleDifference(angle, self.Direction);
end
if( correctingAngle ) then
keyboardRelease( settings.hotkeys.ROTATE_LEFT.key );
keyboardRelease( settings.hotkeys.ROTATE_RIGHT.key );
end
end
self:checkPotions();
self:checkSkills();
yrest(100);
target:update();
self:update();
if( not self:haveTarget() ) then
break;
end
end
self:resetSkills();
if( settings.profile.options.COMBAT_TYPE == "melee" ) then
unregisterTimer("timedAttack");
end
if( type(settings.profile.events.onLeaveCombat) == "function" ) then
local status,err = pcall(settings.profile.events.onLeaveCombat);
if( status == false ) then
local msg = sprintf(language[85], err);
error(msg);
end
end
-- give client a little time to update battle flag, if we loot even at combat
-- we don't need the time
if( settings.profile.options.LOOT_IN_COMBAT ~= true ) then
yrest(800);
end;
-- Monster is dead (0 HP) but still targeted.
-- Loot and clear target.
self:update();
if( self.TargetPtr ~= 0 ) then
local target = CPawn(self.TargetPtr);
if( settings.profile.options.LOOT == true ) then
if( settings.profile.options.LOOT_IN_COMBAT == true ) then
self:loot();
else
if( not self.Battling ) then
-- Skip looting when under attack
self:loot();
end
end
end
self:clearTarget();
end;
self.Fights = self.Fights + 1; -- count our fights
cprintf(cli.green, language[27]); -- Fight finished. Target dead/lost
self.Fighting = false;
end
function CPlayer:loot()
local target = self:getTarget();
if( target == nil or target.Address == 0 ) then
return;
end
local dist = distance(self.X, self.Z, target.X, target.Z);
local hf_x = self.X
local hf_z = self.Z;
local lootdist = 100;
-- Set to combat distance; update later if loot distance is set
if( settings.profile.options.COMBAT_TYPE == "ranged" ) then
lootdist = settings.profile.options.COMBAT_DISTANCE;
end
if( settings.profile.options.LOOT_DISTANCE ) then
lootdist = settings.profile.options.LOOT_DISTANCE;
end
if( dist > lootdist ) then -- only loot when close by
cprintf(cli.green, language[32]); -- Target too far away; not looting.
return false
end
cprintf(cli.green, language[31], dist); -- looting target.
-- "attack" is also the hotkey to loot, strangely.
yrest(500);
keyboardPress(settings.profile.hotkeys.ATTACK.key);
yrest(settings.profile.options.LOOT_TIME + dist*15); -- dist*15 = rough calculation of how long it takes to walk there
-- check for loot problems to give a noob mesassage
self:update();
if( self.X == hf_x and -- we didn't move, seems attack key is not defined
self.Z == hf_z and
dist > 25 ) then
cprintf(cli.yellow, "We didn't move to the loot!? Please be sure you "..
"set ingame the standard attack to hotkey %s.\n",
getKeyName(settings.profile.hotkeys.ATTACK.key) );
end;
-- rnd pause from 3-6 sec after loot to look more human
if( settings.profile.options.LOOT_PAUSE_AFTER > 0 ) then
self:restrnd( settings.profile.options.LOOT_PAUSE_AFTER,3,6);
end;
-- now take a 'step' forward (closes loot bag if full inventory)
keyboardPress(settings.hotkeys.MOVE_FORWARD.key);
-- Maybe take a step forward to pick up a buff.
if( math.random(100) > 80 ) then
keyboardHold(settings.hotkeys.MOVE_FORWARD.key);
yrest(500);
keyboardRelease(settings.hotkeys.MOVE_FORWARD.key);
end
end
function CPlayer:moveTo(waypoint, ignoreCycleTargets)
self:update();
local angle = math.atan2(waypoint.Z - self.Z, waypoint.X - self.X);
local angleDif = angleDifference(angle, self.Direction);
local canTarget = false;
local startTime = os.time();
if( ignoreCycleTargets == nil ) then
ignoreCycleTargets = false;
end;
if( waypoint.Type == WPT_TRAVEL or
waypoint.Type == WPT_RUN ) then
ignoreCycleTargets = true; -- don't target mobs
end;
-- Make sure we don't have a garbage (dead) target
if( self.TargetPtr ~= 0 ) then
local target = CPawn(self.TargetPtr);
if( target.HP <= 1 ) then
self:clearTarget();
end
end
-- no active turning if wander and radius = 0
-- self direction has values from 0 til Pi and -Pi til 0
-- angel has values from 0 til 2*Pi
if(__WPL:getMode() == "wander" and
__WPL:getRadius() == 0 ) then
self:restrnd(100, 1, 4); -- wait 3 sec
if( self.Direction < 0 ) then
angle = (math.pi * 2) - math.abs(self.Direction);
else
angle = self.Direction;
end;
end;
-- QUICK_TURN only
if( settings.profile.options.QUICK_TURN == true ) then
self:faceDirection(angle);
camera:setRotation(angle);
self:update();
angleDif = angleDifference(angle, self.Direction);
end
-- If more than X degrees off, correct before moving.
local rotateStartTime = os.time();
local turningDir = -1; -- 0 = left, 1 = right
while( angleDif > math.rad(65) ) do
if( self.HP < 1 or self.Alive == false ) then
return false, WF_NONE;
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:update();
angleDif = angleDifference(angle, self.Direction);
end
keyboardRelease( settings.hotkeys.ROTATE_LEFT.key );
keyboardRelease( settings.hotkeys.ROTATE_RIGHT.key );
-- direction ok, now look for a target before start movig
if( (not ignoreCycleTargets) and (not self.Battling) ) then
if( self:findTarget() ) then -- find a new target
-- cprintf(cli.turquoise, language[28]); -- stopping waypoint::target acquired
cprintf(cli.turquoise, language[86]); -- stopping waypoint::target acquired before moving
success = false;
failreason = WF_TARGET;
return success, failreason;
end;
end;
local success, failreason = true, WF_NONE;
local dist = distance(self.X, self.Z, waypoint.X, waypoint.Z);
local lastDist = dist;
local lastDistImprove = os.time();
while( dist > 15.0 ) do
if( self.HP < 1 or self.Alive == false ) then
return false, WF_NONE;
end;
if( canTarget == false and os.difftime(os.time(), startTime) > 1 ) then
canTarget = true;
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 )
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_RUN and -- only stop if not waypoint type RUN
os.difftime(os.time(), player.LastAggroTimout ) > 10 ) then -- dont stop 10sec after last aggro wait timeout
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;
-- look for a new target while moving
if( canTarget and (not ignoreCycleTargets) and (not self.Battling) ) then
if( self:findTarget() ) then -- find a new target
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
lastDistImprove = os.time();
lastDist = dist;
elseif( dist > lastDist + 40 ) then
-- Make sure we didn't pass it up
printf(language[29]);
success = false;
failreason = WF_DIST;
break;
end;
if( os.difftime(os.time(), lastDistImprove) > 3 ) then
-- We haven't improved for 3 seconds, assume stuck
success = false;
failreason = WF_STUCK;
break;
end
-- after lastDistImprove time check to avoid wrong messages
self:checkPotions();
self:checkSkills( ONLY_FRIENDLY ); -- only cast friendly spells to ourselfe
dist = distance(self.X, self.Z, waypoint.X, waypoint.Z);
angle = math.atan2(waypoint.Z - self.Z, waypoint.X - self.X);
angleDif = angleDifference(angle, self.Direction);
-- Continue to make sure we're facing the right direction
if( settings.profile.options.QUICK_TURN and angleDif > math.rad(1) ) then
self:faceDirection(angle);
camera:setRotation(angle);
end
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(100);
else
keyboardRelease( settings.hotkeys.ROTATE_LEFT.key );
keyboardHold( settings.hotkeys.ROTATE_RIGHT.key );
yrest(100);
end
elseif( angleDif > math.rad(1) ) then
if( settings.profile.options.QUICK_TURN ) then
camera:setRotation(angle);
end
self:faceDirection(angle);
keyboardRelease( settings.hotkeys.ROTATE_LEFT.key );
keyboardRelease( settings.hotkeys.ROTATE_RIGHT.key );
keyboardHold( settings.hotkeys.MOVE_FORWARD.key );
else
keyboardHold( settings.hotkeys.MOVE_FORWARD.key );
end
--keyboardHold( settings.hotkeys.MOVE_FORWARD.key );
yrest(100);
self:update();
waypoint:update();
end
keyboardRelease( settings.hotkeys.MOVE_FORWARD.key );
keyboardRelease( settings.hotkeys.ROTATE_LEFT.key );
keyboardRelease( settings.hotkeys.ROTATE_RIGHT.key );
if( success ) then
-- We successfully reached the waypoint.
-- Execute it's action, if it has one.
if( waypoint.Action and type(waypoint.Action) == "string" ) then
local actionchunk = loadstring(waypoint.Action);
assert( actionchunk );
actionchunk();
end
end
return success, failreason;
end
-- Forces the player to face a direction.
-- 'dir' should be in radians
function CPlayer:faceDirection(dir)
local Vec1 = math.cos(dir);
local Vec2 = math.sin(dir);
memoryWriteFloat(getProc(), self.Address + chardirXUVec_offset, Vec1);
memoryWriteFloat(getProc(), self.Address + chardirYUVec_offset, Vec2);
end
-- Attempt to unstick the player
function CPlayer:unstick()
-- after 2x unsuccesfull unsticks try to reach last waypoint
if( self.Unstick_counter == 3 ) then
if( self.Returning ) then
__RPL:backward();
else
__WPL:backward();
end;
return;
end;
-- after 5x unsuccesfull unsticks try to reach next waypoint after sticky one
if( self.Unstick_counter == 6 ) then
if( self.Returning ) then
__RPL:advance(); -- forward to sticky wp
__RPL:advance(); -- and one more
else
__WPL:advance(); -- forward to sticky wp
__WPL:advance(); -- and one more
end;
return;
end;
-- after 8x unstick try to run away a little and then go to the nearest waypoint
if( self.Unstick_counter == 9 ) then
-- turn and move back for 10 seconds
keyboardHold(settings.hotkeys.ROTATE_RIGHT.key);
yrest(1900);
keyboardRelease( settings.hotkeys.ROTATE_RIGHT.key );
keyboardHold(settings.hotkeys.MOVE_FORWARD.key);
yrest(10000);
keyboardRelease(settings.hotkeys.MOVE_FORWARD.key);
self:update();
if( player.Returning ) then
__RPL:setWaypointIndex(__RPL:getNearestWaypoint(self.X, self.Z));
else
__WPL:setWaypointIndex(__WPL:getNearestWaypoint(self.X, self.Z));
end;
return;
end;
-- Move back for x seconds
keyboardHold(settings.hotkeys.MOVE_BACKWARD.key);
yrest(1000);
keyboardRelease(settings.hotkeys.MOVE_BACKWARD.key);
-- Straff either left or right now
local straffkey = 0;
if( math.random(100) < 50 ) then
straffkey = settings.hotkeys.STRAFF_LEFT.key;
else
straffkey = settings.hotkeys.STRAFF_RIGHT.key;
end
local straff_bonus = self.Unstick_counter * 120;
keyboardHold(straffkey);
yrest(500 + math.random(500) + straff_bonus);
keyboardRelease(straffkey);
-- try to jump over a obstacle
if( self.Unstick_counter > 1 ) then
if( self.Unstick_counter == 2 ) then
keyboardHold(settings.hotkeys.MOVE_FORWARD.key);
yrest(550);
keyboardPress(settings.hotkeys.JUMP.key);
yrest(400);
keyboardRelease(settings.hotkeys.MOVE_FORWARD.key);
elseif( math.random(100) < 80 ) then
keyboardHold(settings.hotkeys.MOVE_FORWARD.key);
yrest(600);
keyboardPress(settings.hotkeys.JUMP.key);
yrest(400);
keyboardRelease(settings.hotkeys.MOVE_FORWARD.key);
end;
end;
end
function CPlayer:haveTarget()
if( CPawn.haveTarget(self) ) then
local target = self:getTarget();
if( target == nil ) then
return false;
end;
-- check level of target against our leveldif settings
if( ( target.Level - self.Level ) > tonumber(settings.profile.options.TARGET_LEVELDIF_ABOVE) or
( self.Level - target.Level ) > tonumber(settings.profile.options.TARGET_LEVELDIF_BELOW) ) then
if ( self.Battling == false ) then -- if we don't have aggro then
return false; -- he is not a valid target
end;
if( self.Battling == true and -- we have aggro
target.TargetPtr ~= self.Address ) then -- but not from that mob
return false;
end;
end;
-- check if we just ignored that target / ignore it for 10 sec
if(self.TargetPtr == player.Last_ignore_target_ptr and
os.difftime(os.time(), player.Last_ignore_target_time) < 10 )then
if ( self.Battling == false ) then -- if we don't have aggro then
cprintf(cli.green, language[87], target.Name, -- We ignore %s for %s seconds.
10-os.difftime(os.time(), player.Last_ignore_target_time ) );
return false; -- he is not a valid target
end;
if( self.Battling == true and -- we have aggro
target.TargetPtr ~= self.Address ) then -- but not from that mob
return false;
end;
end
-- PK protect
if( target.Type == PT_PLAYER ) then -- Player are type == 1
if ( self.Battling == false ) then -- if we don't have aggro then
return false; -- he is not a valid target
end;
if( self.Battling == true and -- we have aggro
target.TargetPtr ~= self.Address ) then -- but not from the PK player
return false;
end;
end;
-- Friends aren't enemies
if( self:isFriend(target) ) then
if ( self.Battling == false ) then -- if we don't have aggro then
return false; -- he is not a valid target
end;
if( self.Battling == true and -- we have aggro, check if the 'friend' is targeting us
target.TargetPtr ~= self.Address ) then -- but not from that target
return false;
end;
end;
if( settings.profile.options.ANTI_KS ) then
-- Not a valid enemy
if( not target.Attackable ) then
printf(language[30], target.Name);
return false;
end
-- If they aren't targeting us, and they have less than full HP
-- then they must be fighting somebody else.
-- If it's a friend, then it is a valid target; help them.
if( target.TargetPtr ~= self.Address ) then
-- If the target's TargetPtr is 0,
-- that doesn't necessarily mean they don't
-- have a target (game bug, not a bug in the bot)
if( target.TargetPtr == 0 ) then
if( target.HP < target.MaxHP ) then
return false;
end
else
-- They definitely have a target.
-- If it is a friend, we can help.
-- Otherwise, leave it alone.
local targetOfTarget = CPawn(target.TargetPtr);
if( not self:isFriend(targetOfTarget) ) then
return false;
end
end
end
return true;
else
return true;
end
else
return false;
end
end
function CPlayer:update()
-- Ensure that our address hasn't changed. If it has, fix it.
local tmpAddress = memoryReadIntPtr(getProc(), staticcharbase_address, charPtr_offset);
if( tmpAddress ~= self.Address and tmpAddress ~= 0 ) then
self.Address = tmpAddress;
cprintf(cli.green, language[40], self.Address);
end;
CPawn.update(self); -- run base function
self.Casting = (debugAssert(memoryReadInt(getProc(), self.Address + castbar_offset), language[41]) ~= 0);
self.Battling = debugAssert(memoryReadBytePtr(getProc(), staticcharbase_address, inBattle_offset), language[41]) == 1;
-- remember aggro start time, used for timed ranged pull
if( self.Battling == true ) then
if(self.aggro_start_time == 0) then
self.aggro_start_time = os.time();
end
else
self.aggro_start_time = 0;
end
local Vec1 = debugAssert(memoryReadFloat(getProc(), self.Address + chardirXUVec_offset), language[41]);
local Vec2 = debugAssert(memoryReadFloat(getProc(), self.Address + chardirYUVec_offset), language[41]);
if( Vec1 == nil ) then Vec1 = 0.0; end;
if( Vec2 == nil ) then Vec2 = 0.0; end;
self.Direction = math.atan2(Vec2, Vec1);
if( self.Casting == nil or self.Battling == nil or self.Direction == nil ) then
error("Error reading memory in CPlayer:update()");
end
end
function CPlayer:clearTarget()
cprintf(cli.green, language[33]);
memoryWriteInt(getProc(), self.Address + charTargetPtr_offset, 0);
self.TargetPtr = 0;
end
-- returns true if this CPawn is registered as a friend
function CPlayer:isFriend(pawn)
if( not pawn ) then
error("CPlayer:isFriend() received nil\n", 2);
end;
if( not settings ) then
return false;
end;
pawn:update();
for i,v in pairs(settings.profile.friends) do
if(string.lower(pawn.Name) == string.lower(v)) then
return true;
end
end
return false;
end
function CPlayer:logoutCheck()
-- timed logout check
if(self.Battling == true) then
return;
end;
if( settings.profile.options.LOGOUT_TIME > 0 ) then
local elapsed = os.difftime(os.time(), self.BotStartTime);
if( elapsed >= settings.profile.options.LOGOUT_TIME * 60 ) then
self:logout();
end
end
end
function CPlayer:logout(fc_shutdown)
-- importing:
-- fc_shutdown true/false/nil
-- if nil, profile option 'settings.profile.options.LOGOUT_SHUTDOWN'
-- will decide if shutdown or not occurs
cprintf(cli.yellow, language[50], os.date() ); -- Logout at %time%
if( fc_shutdown == nil and settings.profile.options.LOGOUT_SHUTDOWN == true ) then
fc_shutdown = true;
end;
if( settings.profile.hotkeys.LOGOUT_MACRO ) then
keyboardPress(settings.profile.hotkeys.LOGOUT_MACRO.key);
yrest(30000); -- Wait for the log out to process
else
local PID = findProcessByWindow(getWin()); -- Get process ID
os.execute("TASKKILL /PID " .. PID .. " /F");
while(true) do
-- Wait for process to close...
if( findProcessByWindow(__WIN) ~= PID ) then
printf(language[88]);
break;
end;
yrest(100);
end
end
if( fc_shutdown ) then
cprintf(cli.yellow, language[51]);
os.execute("\"%windir%\\system32\\shutdown.exe -s -t 30\" "); --Shutdown in 30 seconds.
end
error("Exiting: Auto-logout", 0); -- Not really an error, but it will drop us back to shell.
end
function CPlayer:check_aggro_before_cast(_jump)
-- break cast in last moment / works not for groups, because you get battling flag from your groupmembers !!!
-- works also if target is not visible and we get aggro from another mob
-- _jump = true abort cast with jump hotkey
self:update();
if( self.Battling == false ) then -- no aggro
return false;
end;
local target = self:getTarget();
if( self.TargetPtr ~= 0 ) then target:update(); end;
-- check if the target is attacking us, if not we can break and take the other mob
if( target.TargetPtr ~= self.Address and -- check HP, because death targets also have not target
target.HP/target.MaxHP*100 > 90 ) then -- target is alive and no attacking us
-- there is a bug in client. Sometimes target is death and so it is not targeting us anymore
-- and at the same time the target HP are above 0
-- so we say > 90% life is alive :-)
if( _jump == true ) then -- jump to abort casting
keyboardPress(settings.hotkeys.JUMP.key);
end;
cprintf(cli.green, language[36], target.Name); -- Aggro during first strike/cast
self:clearTarget();
return true;
end;
end
-- find a target with the ingame target key
-- is used while moving and could also used before moving or after fight
function CPlayer:findTarget()
if(settings.hotkeys.TARGET.modifier) then
keyboardHold(settings.hotkeys.TARGET.modifier);
end
keyboardPress(settings.hotkeys.TARGET.key);
if(settings.hotkeys.TARGET.modifier) then
keyboardRelease(settings.hotkeys.TARGET.modifier);
end
yrest(10);
-- We've got a target, fight it instead of worrying about our waypoint.
if( self:haveTarget() ) then
-- if( self:haveTarget() and self.Fighting == false ) then
-- do we nee self.Fighting == false check?
-- not sure, so I just deleted it to see what happens
-- all other checks are within the self:haveTarget(), so the target should be ok
local target = self:getTarget();
local dist = distance(self.X, self.Z, target.X, target.Z);
cprintf(cli.green, language[37], target.Name, dist); -- Select new target %s in distance
return true;
else
return false;
end;
end
function CPlayer:rest(_restmin, _restmax, _resttype, _restaddrnd)
-- rest to restore mana and healthpoint if under a certain level
-- this function could also be used, if you want to rest in a waypoint file, it will
-- detect aggro while resting and fight back
--
-- player:rest( _restfix,[ _restrnd[, time|full[, _restaddrnd]]])
--
-- _restmin ( minimum rest time in sec)
-- _restmax ( maximum rest time sec)
-- _resttype ( time / full ) time = rest the given time full = stop resting after being full default = time
-- _restaddrnd ( max random addition after being full in sec)
--
-- if using type 'full', the bot will only rest if HP or MP is below a defined level
-- you define that level in your profile with the options MP_REST and HP_REST
--
-- e.g.
-- player:rest(20) will rest for 20 seconds.
-- player:rest(60, 80) will rest between 60 and 80 seconds.
-- player:rest(90, 130, "full") will rest up to between 90 and 130 seconds, and stop resting
-- if being full
-- player:rest(20, 60, "full, 20") will rest up to between 20 and 60 seconds, and stop resting
-- if being full, and wait after that between 1-20 seconds
--
-- to look not so bottish, please use the random time options!!!
--
self:update();
if( self.Battling == true) then return; end; -- if aggro, go back
local hf_resttime;
-- setting default values
if( _restmin == nil or _restmin == 0 ) then _restmin = 10; end;
if( _restmax == nil or _restmax == 0 ) then _restmax = _restmin; end;
if( _resttype == nil ) then _resttype = "time"; end; -- default restype is 'time"
if ( _restmax > _restmin ) then
hf_resttime = _restmin + math.random( _restmax - _restmin );
else
hf_resttime = _restmin;
end;
if( _restaddrnd == nil or _restaddrnd == 0 ) then _restaddrnd = 0;
else _restaddrnd = math.random( _restaddrnd ); end;
-- some classes dont have mana, in that cases Player.mana = 0
local hf_mana_rest = (player.MaxMana * settings.profile.options.MP_REST / 100); -- rest if mana is lower then
local hf_hp_rest = (player.MaxHP * settings.profile.options.HP_REST / 100); -- rest if HP is lower then
if( player.Mana >= hf_mana_rest and player.HP >= hf_hp_rest and
_resttype == 'full' ) then -- nothing to do
return; -- go back
end;
local restStart = os.time(); -- set start timer
if( _resttype == "full") then
cprintf(cli.green, language[38], ( hf_resttime ) ); -- Resting up to %s to fill up mana and HP
else
cprintf(cli.green, language[71], ( hf_resttime ) ); -- Resting for %s seconds.
end;
while ( true ) do
self:update();
if( self.Battling ) then -- we get aggro,
self:clearTarget(); -- get rid of mob to be able to target attackers
cprintf(cli.green, language[39] ); -- get aggro
return;
end;
-- check if resttime finished
if( os.difftime(os.time(), restStart ) > ( hf_resttime ) ) then
cprintf(cli.green, language[70], ( hf_resttime ) ); -- Resting finished after %s seconds
return;
end;
-- check if HP/Mana full
if( player.Mana == player.MaxMana and -- some chars have MaxMana = 0
player.HP == player.MaxHP and
_resttype == "full" ) then -- Mana and HP are full
local restAddStart = os.time(); -- set additional rest timer
while ( true ) do -- rnd addition
self:update();
if( os.difftime(os.time(), restAddStart ) > _restaddrnd ) then
break;
end;
if( self.Battling ) then -- we get aggro,
self:clearTarget(); -- get rid of mob to be able to target attackers
cprintf(cli.green, language[39] ); -- Stop resting because of aggro
return;
end;
self:checkPotions();
self:checkSkills( ONLY_FRIENDLY ); -- only cast friendly spells to ourselfe
yrest(100);
end;
cprintf(cli.green, language[70], os.difftime(os.time(), restStart ) ); -- full after x sec
return;
end;
self:checkPotions();
self:checkSkills( ONLY_FRIENDLY ); -- only cast friendly spells to ourselfe
yrest(100);
end; -- end of while
end
function CPlayer:restrnd(_probability, _restmin, _restmax)
-- call the rest function with a given probability
if( math.random( 100 ) < _probability ) then
self:rest(_restmin, _restmax, "time", 0 )
end;
end
function CPlayer:sleep()
-- the bot will sleep but still fight back attackers
local sleep_start = os.time(); -- calculate the sleep time
self.Sleeping = true; -- we are sleeping
cprintf(cli.yellow, language[89], os.date(), getKeyName(settings.hotkeys.START_BOT.key) );
local hf_key = "";
while(true) do
local hf_key_pressed = false;
-- if( keyPressedLocal(settings.hotkeys.STOP_BOT.key) ) then -- sleep/pause key pressed
-- hf_key_pressed = true;
-- hf_key = "STOP";
-- end;
if( keyPressedLocal(settings.hotkeys.START_BOT.key) ) then -- start key pressed
hf_key_pressed = true;
hf_key = "AWAKE";
end;
if( hf_key_pressed == false ) then -- key released, do the work
-- STOP Key: stop the bot really
-- does not work proper becaus auf the pausecallback assigned to the
-- top key
-- if( hf_key == "STOP" ) then
-- hf_key = " "; -- clear last pressed key
--
-- -- now the stop work is done by the function pauseCallback()
-- -- but we clear the flag to be awake after restart
-- self.Sleeping = false; -- we are awake
-- stopPE(); -- we now really stop the bot
-- return; -- after stop, now go back
-- end;
-- START Key: wake up
if( hf_key == "AWAKE" ) then
hf_key = " "; -- clear last pressed key
cprintf(cli.yellow, language[90], getKeyName(settings.hotkeys.START_BOT.key), os.date() );
self.Sleeping = false; -- we are awake
break;
end;
hf_key = " "; -- clear last pressed key
end;
self:update();
-- wake up if aggro, but we don't clear the sleeping flag
if( self.Battling ) then -- we get aggro,
self:clearTarget(); -- get rid of mob to be able to target attackers
cprintf(cli.yellow, language[91], os.date() ); -- Awake from sleep because of aggro
break;
end;
yrest(10);
self:logoutCheck(); -- check logout timer
end -- end of while
-- count the sleeping time
self.Sleeping_time = self.Sleeping_time + os.difftime(os.time(), sleep_start);
end
function CPlayer:scan_for_NPC(_npcname)
if( foregroundWindow() ~= getWin() ) then
return;
end
local function scan()
local mousePawn;
-- Screen dimension variables
local wx, wy, ww, wh = windowRect(getWin());
local halfWidth = ww/2;
local halfHeight = wh/2;
-- Scan rect variables
local scanWidth = settings.profile.options.HARVEST_SCAN_WIDTH; -- Width, in 'steps', of the area to scan
local scanHeight = settings.profile.options.HARVEST_SCAN_HEIGHT; -- Height, in 'steps', of area to scan
local scanXMultiplier = settings.profile.options.HARVEST_SCAN_XMULTIPLIER; -- multiplier for scan width
local scanYMultiplier = settings.profile.options.HARVEST_SCAN_YMULTIPLIER; -- multiplier for scan line height
local scanStepSize = settings.profile.options.HARVEST_SCAN_STEPSIZE; -- Distance, in pixels, between 'steps'
local mx, my; -- Mouse x/y temp values
mouseSet(wx + (halfWidth*scanXMultiplier - (scanWidth/2*scanStepSize)),
wy + (halfHeight*scanYMultiplier - (scanHeight/2*scanStepSize)));
yrest(200);
local scanstart, scanende, scanstep;
-- define scan direction top/down or bottom/up
if( settings.profile.options.HARVEST_SCAN_TOPDOWN == true ) then
scanstart = 0;
scanende = scanHeight-1;
scanstep = 1;
else
scanstart = scanHeight;
scanende = 0;
scanstep = -1;
end;
-- Scan nearby area for a node
keyboardHold(key.VK_SHIFT); -- press shift so you can scan trough players
for y = scanstart, scanende, scanstep do
my = math.ceil(halfHeight * scanYMultiplier - (scanHeight / 2 * scanStepSize) + ( y * scanStepSize ));
for x = 0,scanWidth-1 do
mx = math.ceil(halfWidth * scanXMultiplier - (scanWidth / 2 * scanStepSize) + ( x * scanStepSize ));
mouseSet(wx + mx, wy + my);
yrest(settings.profile.options.HARVEST_SCAN_YREST+3);
mousePawn = CPawn(memoryReadIntPtr(getProc(), staticcharbase_address, mousePtr_offset));
-- id 110504 Waffenhersteller Dimar
-- id 110502 Dan (Gemischtwarenhändler
-- id 1000, 1001 Player
if( mousePawn.Address ~= 0 and mousePawn.Type == PT_NPC
and distance(self.X, self.Z, mousePawn.X, mousePawn.Z) < 150
and mousePawn.Id > 100000 ) then
local target = CPawn(mousePawn.Address);
if( _npcname and -- check ncp name
not string.find(target.Name, _npcname ) ) then
local dummy = 1; -- do nothing
else
cprintf(cli.green, "We found NPC: %s\n", target.Name);
return mousePawn.Address, mx, my;
end;
end
end
end
keyboardRelease(key.VK_SHIFT);
return 0, nil, nil;
end
detach(); -- Remove attach bindings
local mouseOrigX, mouseOrigY = mouseGetPos();
local foundHarvestNode, nodeMouseX, nodeMouseY = scan();
if( foundHarvestNode ~= 0 and nodeMouseX and nodeMouseY ) then
-- If out of distance, move and rescan
local mousePawn = CPawn(foundHarvestNode);
local dist = distance(self.X, self.Z, mousePawn.X, mousePawn.Z)
if( dist > 35 and dist < 150 ) then
printf(language[80]); -- Move in
self:moveTo( CWaypoint(mousePawn.X, mousePawn.Z), true );
yrest(200);
foundHarvestNode, nodeMouseX, nodeMouseY = scan();
end
self:update();
local wx,wy = windowRect(getWin());
--mouseSet(wx + nodeMouseX, wy + nodeMouseY);
mouseSet(wx + nodeMouseX, wy + nodeMouseY);
yrest(3000); -- wait for zoom in / out movement bug
-- click NPC
keyboardHold(key.VK_SHIFT);
mouseLClick(); -- one click to target npc
yrest(500);
mouseLClick(); -- one click to open dialog
yrest(500);
mouseLClick(); -- one click to be really sure
keyboardRelease(key.VK_SHIFT);
self:update();
yrest(2000);
end
mouseSet(mouseOrigX, mouseOrigY);
attach(getWin()); -- Re-attach bindings
end
function CPlayer:mouseclickL(_x, _y, _wwide, _whigh)
if( foregroundWindow() ~= getWin() ) then
return;
end
detach(); -- Remove attach bindings
local wx,wy,wwide,whigh = windowRect(getWin());
local hf_x, hf_y;
-- recalulate clickpoints depending from the actual RoM windows size
-- only if we know the original windows size from the clickpoints
if(_wwide and _whigh) then
hf_x = wwide * _x / _wwide;
hf_y = whigh * _y / _whigh;
cprintf(cli.green, language[92], -- Mouseclick Left at %d,%d in %dx%d (recalculated
hf_x, hf_y, wwide, whigh, _x, _y, _wwide, _whigh);
else
hf_x = _x;
hf_y = _y;
cprintf(cli.green, language[93], -- Clicking mouseL at %d,%d in %dx%d\n
hf_x, hf_y, wwide, whigh);
end;
mouseSet(wx + hf_x, wy + hf_y);
yrest(100);
mouseLClick();
yrest(100);
attach(getWin()); -- Re-attach bindings
end
function CPlayer:target_NPC(_npcname)
if( not _npcname ) then
cprintf(cli.yellow, "target_NPC(): Please give a NPC name for using that function.\n");
return
end
if(settings.hotkeys.TARGET_FRIEND.modifier) then
cprintf(cli.yellow, "Due to technical reasons, we don't support "..
"modifiers like CTRL/ALT/SHIFT for hotkeys at the moment. "..
"Please change your hotkey %s-%s for hotkey TARGET_FRIEND.\n",
getKeyName(settings.hotkeys.TARGET_FRIEND.modifier),
getKeyName(settings.hotkeys.TARGET_FRIEND.key) );
return
end
cprintf(cli.green, "We try to find NPC %s: ", _npcname);
local hf_temp;
for i = 1, 10 do
if(settings.hotkeys.TARGET_FRIEND.modifier) then
keyboardHold(settings.hotkeys.TARGET_FRIEND.modifier);
end
keyboardPress(settings.hotkeys.TARGET_FRIEND.key);
if(settings.hotkeys.TARGET_FRIEND.modifier) then
keyboardRelease(settings.hotkeys.TARGET_FRIEND.modifier);
end
player:update();
if(player.TargetPtr ~= 0) then
hf_temp = true; -- we found something
local target = self:getTarget(); -- read target informations
cprintf(cli.green, "%s, ", target.Name); -- print name
if( string.find(string.lower(target.Name), string.lower(_npcname) ) ) then
cprintf(cli.green, "\nWe successfully target NPC %s and try "..
"to open dialog window.\n", _npcname);
if( settings.profile.hotkeys.ATTACK.modifier ) then
keyboardHold(settings.hotkeys.ATTACK.modifier);
end
keyboardPress(settings.profile.hotkeys.ATTACK.key);
if( settings.profile.hotkeys.ATTACK.modifier ) then
keyboardRelease(settings.profile.hotkeys.ATTACK.modifier);
end
return true;
end
end;
yrest(500);
end
cprintf(cli.green, "Sorry, we can't find NPC %s.\n", _npcname);
if( not hf_temp) then
cprintf(cli.yellow, "We didn't found any NPC! Have you set "..
"your ingame target friendly key to %s?\n",
getKeyName(settings.hotkeys.TARGET_FRIEND.key) );
end
return false;
end
Re: Bad argument #1 to getkeyname
Please post your settings.xml and your RoM/bindings.txt. Seems your rotate left key is wrong. And the content of the MM window (after starting the bot) would also be nice. There we can see, if the bot uses the settings.lua or the bindings.txtSuffering wrote:Thanks for all your help so far,but im still getting problems.This time its:
player.lua:748 bad argument #1 to 'keyboardrelease' <<null>>
my player.lua:
The RoM Bot Online Wiki needs your help!
Re: Bad argument #1 to getkeyname
blah blah,
RoM windows size is 0x0 upper left corner -32000,-32000
loaded waypoint path bigharvest.xml
loaded return path bighavest.xml
we use the normal waypoint path bigharvest.xml now.
moving to waypoint #63,<COORDINATES>
blahbalh/classes/player.lua:<insert the error here>
Settings.xml:
bindings txt:
And i actually had my Q button unbinded so i could use this as my ventrilo talk button.would this interfere with the bot?
RoM windows size is 0x0 upper left corner -32000,-32000
loaded waypoint path bigharvest.xml
loaded return path bighavest.xml
we use the normal waypoint path bigharvest.xml now.
moving to waypoint #63,<COORDINATES>
blahbalh/classes/player.lua:<insert the error here>
Settings.xml:
Code: Select all
<settings>
<hotkeys>
<!-- Cannot use modifiers -->
<hotkey description="MOVE_FORWARD" key="VK_W" modifier="" />
<hotkey description="MOVE_BACKWARD" key="VK_S" modifier="" />
<hotkey description="ROTATE_LEFT" key="VK_Q" modifier="" />
<hotkey description="ROTATE_RIGHT" key="VK_E" modifier="" />
<hotkey description="STRAFF_LEFT" key="VK_A" modifier="" />
<hotkey description="STRAFF_RIGHT" key="VK_D" modifier="" />
<hotkey description="JUMP" key="VK_SPACE" modifier="" />
<hotkey description="TARGET" key="VK_TAB" modifier="" />
<hotkey description="TARGET_FRIEND" key="VK_J" modifier="" />
</hotkeys>
<options>
<option name="ENABLE_FIGHT_SLOW_TURN" value="false" />
<option name="MELEE_DISTANCE" value="45" />
<option name="LANGUAGE" value="english" />
<option name="DEBUG_ASSERT" value="true" />
</options>
</settings>
Code: Select all
i have no bindings.txt in my RoM folder.
Re: Bad argument #1 to getkeyname
Got it working.Thanks for all your help,i'll post back here if i have any further problems.i'll inform you if i have that memory error after an hour of botting too.
Re: Bad argument #1 to getkeyname
The bindings.txt is in your 'My Documents/Runes of Magic' folder. And you suppress evidence material ! There must be some green message at the begin of the MM protocal where the bot says, that he found and reads your bindings.txtSuffering wrote:bindings txt:And i actually had my Q button unbinded so i could use this as my ventrilo talk button.would this interfere with the bot?Code: Select all
i have no bindings.txt in my RoM folder.
And there is no rotate left button. I suppose you use your mouse You have ingame to assign one.
The RoM Bot Online Wiki needs your help!
Re: Bad argument #1 to getkeyname
Thx for your endurance and patience. We can now to the checks a little better to avoid misconfigurations in the future.Suffering wrote:Got it working.Thanks for all your help,i'll post back here if i have any further problems.i'll inform you if i have that memory error after an hour of botting too.
The RoM Bot Online Wiki needs your help!
Re: Bad argument #1 to getkeyname
Yet another problem.My bot doesn't search for anything at its harvest points.Heres my harvest xml file
hmmmm heres my profile:
my settings.lua
Code: Select all
<waypoints type="TRAVEL">
<!-- # 1 --><waypoint x="-1223" z="-5392">player:harvest();</waypoint>
<!-- # 2 --><waypoint x="-1247" z="-5303">player:harvest();</waypoint>
<!-- # 3 --><waypoint x="-1149" z="-5174">player:harvest();</waypoint>
<!-- # 4 --><waypoint x="-954" z="-5146">player:harvest();</waypoint>
<!-- # 5 --><waypoint x="-702" z="-5153">player:harvest();</waypoint>
<!-- # 6 --><waypoint x="-130" z="-4862">player:harvest();</waypoint>
<!-- # 7 --><waypoint x="-189" z="-4702">player:harvest();</waypoint>
<!-- # 8 --><waypoint x="67" z="-4499">player:harvest();</waypoint>
<!-- # 9 --><waypoint x="115" z="-4427"></waypoint>
<!-- #10 --><waypoint x="274" z="-4435">player:harvest();</waypoint>
<!-- #11 --><waypoint x="23" z="-4257"></waypoint>
<!-- #12 --><waypoint x="-140" z="-4158">player:harvest();</waypoint>
<!-- #13 --><waypoint x="69" z="-4099">player:harvest();</waypoint>
<!-- #14 --><waypoint x="-16" z="-3948">player:harvest();</waypoint>
<!-- #15 --><waypoint x="48" z="-3760">player:harvest();</waypoint>
<!-- #16 --><waypoint x="46" z="-3428">player:harvest();</waypoint>
<!-- #17 --><waypoint x="81" z="-3311">player:harvest();</waypoint>
<!-- #18 --><waypoint x="-87" z="-3325">player:restrnd(100, 5, 20)</waypoint>
<!-- #19 --><waypoint x="-44" z="-3323">player:harvest();</waypoint>
<!-- #20 --><waypoint x="-103" z="-3444">player:harvest();</waypoint>
<!-- #21 --><waypoint x="-339" z="-3649">player:harvest();</waypoint>
<!-- #22 --><waypoint x="-708" z="-3420">player:harvest();</waypoint>
<!-- #23 --><waypoint x="-668" z="-3195">player:harvest();</waypoint>
<!-- #24 --><waypoint x="-635" z="-3231">player:harvest();</waypoint>
<!-- #25 --><waypoint x="-635" z="-3471"></waypoint>
<!-- #26 --><waypoint x="-877" z="-3694">player:harvest();</waypoint>
<!-- #27 --><waypoint x="-985" z="-3586">player:harvest();</waypoint>
<!-- #28 --><waypoint x="-963" z="-3739"></waypoint>
<!-- #29 --><waypoint x="-1016" z="-3854"></waypoint>
<!-- #30 --><waypoint x="-1030" z="-3826">player:harvest();</waypoint>
<!-- #31 --><waypoint x="-1159" z="-3823"></waypoint>
<!-- #32 --><waypoint x="-1267" z="-3982"></waypoint>
<!-- #33 --><waypoint x="-1292" z="-3886">player:harvest();</waypoint>
<!-- #34 --><waypoint x="-1403" z="-4133">player:harvest();</waypoint>
<!-- #35 --><waypoint x="-1516" z="-4087">player:harvest();</waypoint>
<!-- #36 --><waypoint x="-1665" z="-3790">player:harvest();</waypoint>
<!-- #37 --><waypoint x="-1705" z="-3708">player:harvest();</waypoint>
<!-- #38 --><waypoint x="-1472" z="-3505">player:harvest();</waypoint>
<!-- #39 --><waypoint x="-1654" z="-3585"></waypoint>
<!-- #40 --><waypoint x="-1879" z="-3653"></waypoint>
<!-- #41 --><waypoint x="-2023" z="-3842"></waypoint>
<!-- #42 --><waypoint x="-2183" z="-4188">player:harvest();</waypoint>
<!-- #43 --><waypoint x="-2232" z="-4269">player:harvest();</waypoint>
<!-- #44 --><waypoint x="-2052" z="-4302">player:harvest();</waypoint>
<!-- #45 --><waypoint x="-2320" z="-4323"></waypoint>
<!-- #46 --><waypoint x="-2406" z="-4173">player:harvest();</waypoint>
<!-- #47 --><waypoint x="-2628" z="-4089">player:harvest();</waypoint>
<!-- #48 --><waypoint x="-2675" z="-3814">player:harvest();</waypoint>
<!-- #49 --><waypoint x="-2506" z="-3865">player:harvest();</waypoint>
<!-- #50 --><waypoint x="-2600" z="-3522">player:harvest();</waypoint>
<!-- #51 --><waypoint x="-2842" z="-3331">player:harvest();</waypoint>
<!-- #52 --><waypoint x="-2737" z="-3084">player:harvest();</waypoint>
<!-- #53 --><waypoint x="-3143" z="-3122">player:harvest();</waypoint>
<!-- #54 --><waypoint x="-3264" z="-3203">player:harvest();</waypoint>
<!-- #55 --><waypoint x="-3365" z="-3206"></waypoint>
<!-- #56 --><waypoint x="-3377" z="-3174">player:harvest();</waypoint>
<!-- #57 --><waypoint x="-3489" z="-3235">player:harvest();</waypoint>
<!-- #58 --><waypoint x="-3785" z="-3295">player:harvest();</waypoint>
<!-- #59 --><waypoint x="-3769" z="-3065">player:harvest();</waypoint>
<!-- #60 --><waypoint x="-3641" z="-3224"></waypoint>
<!-- #61 --><waypoint x="-3489" z="-3583">player:harvest();</waypoint>
<!-- #62 --><waypoint x="-3484" z="-3757">player:harvest();</waypoint>
<!-- #63 --><waypoint x="-3185" z="-4067">player:harvest();</waypoint>
<!-- #64 --><waypoint x="-3368" z="-4048">player:harvest();</waypoint>
<!-- #65 --><waypoint x="-2943" z="-4040"></waypoint>
<!-- #66 --><waypoint x="-2654" z="-4086">player:harvest();</waypoint>
<!-- #67 --><waypoint x="-2422" z="-4161">player:harvest();</waypoint>
<!-- #68 --><waypoint x="-2202" z="-4200">player:harvest();</waypoint>
<!-- #69 --><waypoint x="-2056" z="-4295">player:harvest();</waypoint>
<!-- #70 --><waypoint x="-1847" z="-4389">player:harvest();</waypoint>
<!-- #71 --><waypoint x="-1592" z="-4034">player:harvest();</waypoint>
<!-- #72 --><waypoint x="-1537" z="-4075">player:harvest();</waypoint>
<!-- #73 --><waypoint x="-1303" z="-3879">player:harvest();</waypoint>
<!-- #74 --><waypoint x="-1049" z="-3820">player:harvest();</waypoint>
<!-- #75 --><waypoint x="-917" z="-3790"></waypoint>
<!-- #76 --><waypoint x="-891" z="-3715">player:harvest();</waypoint>
<!-- #77 --><waypoint x="-980" z="-3591">player:harvest();</waypoint>
<!-- #78 --><waypoint x="-887" z="-3589"></waypoint>
<!-- #79 --><waypoint x="-738" z="-3565"></waypoint>
<!-- #80 --><waypoint x="-689" z="-3454"></waypoint>
<!-- #81 --><waypoint x="-712" z="-3425">player:harvest();</waypoint>
<!-- #82 --><waypoint x="-665" z="-3187">player:harvest();</waypoint>
<!-- #83 --><waypoint x="-722" z="-3051">player:harvest();</waypoint>
<!-- #84 --><waypoint x="-454" z="-2930"></waypoint>
<!-- #85 --><waypoint x="-349" z="-2922"></waypoint>
<!-- #86 --><waypoint x="-351" z="-2860">player:harvest();</waypoint>
<!-- #87 --><waypoint x="-115" z="-2770"></waypoint>
<!-- #88 --><waypoint x="48" z="-2819">player:harvest();</waypoint>
<!-- #89 --><waypoint x="105" z="-2487">player:harvest();</waypoint>
<!-- #90 --><waypoint x="-111" z="-2548"></waypoint>
<!-- #91 --><waypoint x="-376" z="-2485"></waypoint>
<!-- #92 --><waypoint x="-407" z="-2458">player:harvest();</waypoint>
<!-- #93 --><waypoint x="-524" z="-2624"></waypoint>
<!-- #94 --><waypoint x="-535" z="-2806"></waypoint>
<!-- #95 --><waypoint x="-548" z="-3049"></waypoint>
<!-- #96 --><waypoint x="-496" z="-3234"></waypoint>
<!-- #97 --><waypoint x="-468" z="-3424"></waypoint>
<!-- #98 --><waypoint x="-467" z="-3622"></waypoint>
<!-- #99 --><waypoint x="-360" z="-3658">player:harvest();</waypoint>
</waypoints>
Code: Select all
<profile>
<options>
<!-- Try the bot with a new char mage or priest -->
<!-- At the pioneer village. Use demo.xml waypoint file -->
<option name="HP_LOW" value="85" />
<option name="MP_LOW_POTION" value="50" />
<option name="HP_LOW_POTION" value="40" />
<option name="POTION_COOLDOWN" value="15" />
<!-- Combat options -->
<option name="COMBAT_TYPE" value="ranged" /> <!-- Choose ranged/melee if not using class default -->
<option name="COMBAT_RANGED_PULL" value="false" /> <!-- only important for melees -->
<option name="COMBAT_DISTANCE" value="500" />
<option name="MAX_FIGHT_TIME" value="15" /> <!-- Max time without damage before break -->
<option name="DOT_PERCENT" value="90" />
<option name="ANTI_KS" value="true" />
<!-- Waypoint and movement settings -->
<option name="WAYPOINTS" value="bigharvest.xml" />
<option name="RETURNPATH" value="bigharvest.xml" />
<option name="PATH_TYPE" value="waypoints" /> <!-- waypoints | wander -->
<option name="WANDER_RADIUS" value="500" />
<option name="WAYPOINT_DEVIATION" value="0" />
<option name="QUICK_TURN" value="true" />
<!-- Attack monsters 3 levels above or 10 below your level -->
<option name="TARGET_LEVELDIF_ABOVE" value="3" />
<option name="TARGET_LEVELDIF_BELOW" value="10" />
<!-- Loot settings -->
<option name="LOOT" value="true" />
<option name="LOOT_IN_COMBAT" value="true" />
<option name="LOOT_DISTANCE" value="100" />
<option name="LOOT_PAUSE_AFTER" value="10" /> <!-- probability in % for a short rest -->
<!-- Rest if HP or Mana is below that level -->
<option name="HP_REST" value="15" />
<option name="MP_REST" value="15" />
<!-- Log out and resurrect settings -->
<option name="LOGOUT_TIME" value="0" /> <!-- in minutes, 0 = timer disabled -->
<option name="LOGOUT_SHUTDOWN" value="false" />
<option name="LOGOUT_WHEN_STUCK" value="true" />
<option name="RES_AUTOMATIC_AFTER_DEATH" value="true" />
</options>
<friends>
<!-- names of friends we help fighting or enemys we don't want to attack -->
<friend name="MyOtherCharacter1" />
<friend name="MyOtherCharacter2" />
<friend name="Elite_Mob_Name1" />
<friend name="Elite_Mob_Name2" />
</friends>
<hotkeys>
<hotkey name="HP_POTION" key="VK_MINUS" />
<hotkey name="MP_POTION" key="VK_PLUS" />
<hotkey name="ATTACK" key="VK_0" />
<hotkey name="RES_MACRO" key="VK_9" />
<hotkey name="LOGOUT_MACRO" key="VK_8" />
</hotkeys>
<!-- define your skills depending from your actual primary class -->
<!-- see the example for a priest/mage respectively mage/priest -->
<!-- delete skills you don't have or don't want to use. -->
<!-- For more skills to use see /database/skills.xml -->
<!-- demo skills for LvL 1 character for all classes -->
<skills_priest>
<skill name="PRIEST_SOUL_SOURCE" hotkey="VK_4" priority="110" inbattle="true" hpper="15" />
<skill name="PRIEST_HOLY_AURA" hotkey="VK_7" priority="100" inbattle="true" hpper="24" />
<skill name="PRIEST_URGENT_HEAL" hotkey="" priority="100" hpper="30" />
<skill name="PRIEST_REGENERATE" hotkey="VK_6" priority="90" />
<skill name="PRIEST_RISING_TIDE" hotkey="VK_3" priority="80" />
<skill name="MAGE_FIREBALL" hotkey="VK_2" priority="70" />
<skill name="PRIEST_WAVE_ARMOR" hotkey="VK_5" priority="40" inbattle="true" />
<!--skill name="PRIEST_SOUL_BOND" hotkey="VK_T" priority="30" /> -->
<!--skill name="PRIEST_MAGIC_BARRIER" hotkey="VK_F" priority="20" /> -->
</skills_priest>
<skills_warrior>
<skill name="WARRIOR_SLASH" hotkey="VK_2" priority="90" />
<skill name="WARRIOR_PROBING_ATTACK" hotkey="VK_4" priority="80" />
<skill name="WARRIOR_OPEN_FLANK" hotkey="VK_5" priority="70" />
</skills_warrior>
<skills_scout>
<skill name="SCOUT_SHOT" hotkey="VK_2" priority="90" />
<skill name="SCOUT_AUTOSHOT" hotkey="VK_4" priority="80" />
<skill name="SCOUT_WIND_ARROWS" hotkey="VK_5" priority="70" />
</skills_scout>
<skills_rogue>
<skill name="ROGUE_SHADOWSTAB" hotkey="VK_2" priority="90" />
<skill name="ROGUE_LOW_BLOW" hotkey="VK_4" priority="80" />
</skills_rogue>
<skills_mage>
<skill name="MAGE_FLAME" hotkey="VK_1" priority="80" />
</skills_mage>
<skills_knight>
</skills_knight>
<skills_runedancer>
</skills_runedancer>
<skills_druid>
</skills_druid>
<onDeath>
-- Additional Lua code to execute on death
-- pauseOnDeath(); -- Stop the script
</onDeath>
<onLeaveCombat>
-- Additional Lua code to execute after killing an enemy
</onLeaveCombat>
<onSkillCast>
-- Additional Lua code to execute when casting a skill
-- Note: arg1 contains the skill being used.
-- i.e. arg1.Name will be the name of the skill being cast.
</onSkillCast>
</profile>
Code: Select all
settings_default = {
hotkeys = {
MOVE_FORWARD = {key = _G.key.VK_W, modifier = nil},
MOVE_BACKWARD = {key = _G.key.VK_S, modifier = nil},
ROTATE_LEFT = {key = _G.key.VK_A, modifier = nil},
ROTATE_RIGHT = {key = _G.key.VK_D, modifier = nil},
STRAFF_LEFT = {key = _G.key.VK_Q, modifier = nil},
STRAFF_RIGHT = {key = _G.key.VK_E, modifier = nil},
JUMP = {key = _G.key.VK_SPACE, modifier = nil},
TARGET = {key = _G.key.VK_TAB, modifier = nil},
TARGET_FRIEND = {key = _G.key.J, modifier = nil},
START_BOT = {key = _G.key.VK_DELETE, modifier = nil},
STOP_BOT = {key = _G.key.VK_END, modifier = nil}
},
options = {
ENABLE_FIGHT_SLOW_TURN = false,
MELEE_DISTANCE = 45,
LANGUAGE = "english",
DEBUG_ASSERT = false,
},
profile = {
options = {
-- common options
HP_LOW = 85,
MP_LOW_POTION = 50,
HP_LOW_POTION = 40,
COMBAT_TYPE = "melee",
COMBAT_RANGED_PULL = "true", -- only for melee classes
COMBAT_DISTANCE = 200,
ANTI_KS = true,
WAYPOINTS = "myWaypoints.xml",
RETURNPATH = nil,
PATH_TYPE = "waypoints",
WANDER_RADIUS = 500,
WAYPOINT_DEVIATION = 0,
LOOT = true,
LOOT_TIME = 2000,
LOOT_IN_COMBAT = true,
LOOT_DISTANCE = nil,
LOOT_PAUSE_AFTER = 10, -- probability for short pause after loot to look more human
POTION_COOLDOWN = 15,
MAX_FIGHT_TIME = 12,
DOT_PERCENT = 90,
LOGOUT_TIME = 0,
LOGOUT_SHUTDOWN = false,
LOGOUT_WHEN_STUCK = true,
MAX_UNSTICK_TRIALS = 10,
TARGET_LEVELDIF_BELOW = 99,
TARGET_LEVELDIF_ABOVE = 99,
QUICK_TURN = false,
MP_REST = 15,
HP_REST = 15,
RES_AUTOMATIC_AFTER_DEATH = false, -- automatic resurrect after death true | false,
-- expert options
WAYPOINTS_REVERSE = false, -- use the waypoint file in reverse order
MAX_DEATHS = 10, -- maximal death if automatic resurrect befor logout
WAIT_TIME_AFTER_RES = 8000, -- time to wait after resurrection, needs more on slow PCs
RETURNPATH_SUFFIX = "_return", -- suffix for default naming of returnpath
HARVEST_SCAN_WIDTH = 10, -- steps horizontal
HARVEST_SCAN_HEIGHT = 8, -- steps vertical
HARVEST_SCAN_STEPSIZE = 35, -- wide of every step
HARVEST_SCAN_TOPDOWN = true, -- true = top->down false = botton->up
HARVEST_SCAN_XMULTIPLIER = 1.0, -- multiplier for scan width
HARVEST_SCAN_YMULTIPLIER = 1.1, -- multiplier for scan line height
HARVEST_SCAN_YREST = 10, -- scanspeed
USE_SLEEP_AFTER_RESUME = false, -- enter sleep mode afer pressing pause key
}, hotkeys = {}, skills = {}, friends = {},
events = {
onDeath = function () pauseOnDeath(); end,
onLoad = nil,
onLeaveCombat = nil,
onSkillCast = nil,
}
},
};
settings = settings_default;
-- check if keys are double assigned or empty
check_keys = { };
function check_double_key_settings( _name, _key, _modifier )
--if( _modifier == "" ) then _modifier = nil; end;
for i,v in pairs(check_keys) do
if( v.key == _key and
v.modifier == _modifier ) then
local modname, keyname;
if( v.modifier ) then modname = getKeyName(v.modifier); end;
if( v.key ) then keyname = getKeyName(v.key); end;
local errstr = sprintf("Error: You assigned the key \'%s %s\' double: for \'%s\' and for \'%s\'.\n",
tostring(modname), tostring(keyname), v.name, _name) .. "Please check your settings!";
error(errstr, 0);
if( _key == nil) then
cprintf(cli.yellow, "Error: The key for \'%s\' is empty!\n", _name);
error("Please check your settings!", 0);
end
end
end;
-- check the using of modifiers
if( _modifier ~= nil) then
local modname, keyname;
if( _modifier ) then modname = getKeyName(_modifier); end;
if( _key ) then keyname = getKeyName(_key); end;
cprintf(cli.yellow, "Due to technical reasons, we don't support "..
"modifiers like CTRL/ALT/SHIFT for hotkeys at the moment. "..
"Please change your hotkey %s-%s for \'%s\'\n", tostring(modname), tostring(keyname), _name);
-- only a warning for TARGET_FRIEND / else an error
if(_name == "TARGET_FRIEND") then
cprintf(cli.yellow, "You can't use the player:target_NPC() function until changed!\n");
else
error("Please check your settings!", 0);
end
end
local tmp = {};
tmp.name = _name;
tmp.key = _key;
tmp.modifier = _modifier;
table.insert(check_keys, tmp);
end
function settings.load()
local filename = getExecutionPath() .. "/settings.xml";
local root = xml.open(filename);
local elements = root:getElements();
-- Specific to loading the hotkeys section of the file
local loadHotkeys = function (node)
local elements = node:getElements();
for i,v in pairs(elements) do
-- If the hotkey doesn't exist, create it.
settings.hotkeys[ v:getAttribute("description") ] = { };
settings.hotkeys[ v:getAttribute("description") ].key = key[v:getAttribute("key")];
settings.hotkeys[ v:getAttribute("description") ].modifier = key[v:getAttribute("modifier")];
if( key[v:getAttribute("key")] == nil ) then
local err = sprintf("settings.xml error: %s does not have a valid hotkey!", v:getAttribute("description"));
error(err, 0);
end
check_double_key_settings( v:getAttribute("description"), v:getAttribute("key"), v:getAttribute("modifier") );
end
end
local loadOptions = function (node)
local elements = node:getElements();
for i,v in pairs(elements) do
settings.options[ v:getAttribute("name") ] = v:getAttribute("value");
end
end
-- load RoM keyboard bindings.txt file
local function load_RoM_bindings_txt()
local filename, file;
local userprofilePath = os.getenv("USERPROFILE");
local documentPaths = {
userprofilePath .. "\\My Documents\\", -- English
userprofilePath .. "\\Eigene Dateien\\", -- German
userprofilePath .. "\\Mes Documents\\", -- French
userprofilePath .. "\\Omat tiedostot\\", -- Finish
userprofilePath .. "\\Belgelerim\\", -- Turkish
userprofilePath .. "\\Mina Dokument\\", -- Swedish
userprofilePath .. "\\Dokumenter\\", -- Danish
userprofilePath .. "\\Documenti\\", -- Italian
userprofilePath .. "\\Mijn documenten\\", -- Dutch
userprofilePath .. "\\Moje dokumenty\\", -- Polish
userprofilePath .. "\\Mis documentos\\", -- Spanish
-- "F:\\privat\\",
};
-- Select the first path that exists
for i,v in pairs(documentPaths) do
local filename = v .. "Runes of Magic\\bindings.txt"
if( fileExists(filename) ) then
file = io.open(filename, "r");
cprintf(cli.green, "We read the hotkey settings from your "..
"bindings.txt file %s instead of using the settings.lua file.\n", filename)
end
end
-- If we wern't able to locate a document path, return.
if( file == nil ) then
return;
end
-- Load bindings.txt into own table structure
bindings = { name = { } };
-- read the lines in table 'lines'
for line in file:lines() do
for name, key1, key2 in string.gfind(line, "(%w*)%s([%w+]*)%s*([%w+]*)") do
bindings[name] = {};
bindings[name].key1 = key1;
bindings[name].key2 = key2;
--settings.hotkeys[name].key =
end
end
local function bindHotkey(bindingName)
local links = { -- Links forward binding names to hotkey names
MOVEFORWARD = "MOVE_FORWARD",
MOVEBACKWARD = "MOVE_BACKWARD",
TURNLEFT = "ROTATE_LEFT",
TURNRIGHT = "ROTATE_RIGHT",
STRAFELEFT = "STRAFF_LEFT",
STRAFERIGHT = "STRAFF_RIGHT",
TARGETNEARESTENEMY = "TARGET",
TARGETNEARESTFRIEND = "TARGET_FRIEND",
};
local hotkeyName = bindingName;
if(links[bindingName] ~= nil) then
hotkeyName = links[bindingName];
end;
if( bindings[bindingName] ~= nil ) then
if( bindings[bindingName].key1 ~= nil ) then
-- Fix key names
bindings[bindingName].key1 = string.gsub(bindings[bindingName].key1, "CTRL", "CONTROL");
if( string.find(bindings[bindingName].key1, '+') ) then
local parts = explode(bindings[bindingName].key1, '+');
-- parts[1] = modifier
-- parts[2] = key
settings.hotkeys[hotkeyName].key = key["VK_" .. parts[2]];
settings.hotkeys[hotkeyName].modifier = key["VK_" .. parts[1]];
else
settings.hotkeys[hotkeyName].key = key["VK_" .. bindings[bindingName].key1];
end
check_double_key_settings( hotkeyName, settings.hotkeys[hotkeyName].key,
settings.hotkeys[hotkeyName].modifier );
end
end
end
bindHotkey("MOVEFORWARD");
bindHotkey("MOVEBACKWARD");
bindHotkey("TURNLEFT");
bindHotkey("TURNRIGHT");
bindHotkey("STRAFELEFT");
bindHotkey("STRAFERIGHT");
bindHotkey("JUMP");
bindHotkey("TARGETNEARESTENEMY");
bindHotkey("TARGETNEARESTFRIEND");
end
-- check ingame settings
-- only if we can find the bindings.txt file
local function check_ingame_settings( _name, _ingame_key)
if( not bindings ) then -- no bindings.txt file loaded
return
end;
if( settings.hotkeys[_name].key ~= key["VK_"..bindings[_ingame_key].key1] and
settings.hotkeys[_name].key ~= key["VK_"..bindings[_ingame_key].key2] ) then
cprintf(cli.yellow, "Your bot settings for hotkey \'%s\' in settings.xml "..
"don't match your RoM ingame keyboard settings.\n",
_name);
error("Please check your settings!", 0);
end
end
function checkHotkeys(_name, _ingame_key)
if( not settings.hotkeys[_name] ) then
error("ERROR: Global hotkey not set: " .. _name, 0);
end
-- check if settings.lua hotkeys match the RoM ingame settings
-- check_ingame_settings( _name, _ingame_key);
end
for i,v in pairs(elements) do
local name = v:getName();
if( string.lower(name) == "hotkeys" ) then
loadHotkeys(v);
elseif( string.lower(name) == "options" ) then
loadOptions(v);
end
end
load_RoM_bindings_txt(); -- read bindings.txt from RoM user folder
-- Check to make sure everything important is set
-- bot hotkey name RoM ingame key name
checkHotkeys("MOVE_FORWARD", "MOVEFORWARD");
checkHotkeys("MOVE_BACKWARD", "MOVEBACKWARD");
checkHotkeys("ROTATE_LEFT", "TURNLEFT");
checkHotkeys("ROTATE_RIGHT", "TURNRIGHT");
checkHotkeys("STRAFF_LEFT", "STRAFELEFT");
checkHotkeys("STRAFF_RIGHT", "STRAFERIGHT");
checkHotkeys("JUMP", "JUMP");
checkHotkeys("TARGET", "TARGETNEARESTENEMY");
checkHotkeys("TARGET_FRIEND", "TARGETNEARESTFRIEND");
end
function settings.loadProfile(_name)
-- Delete old profile settings (if they even exist), restore defaults
settings.profile = settings_default.profile;
local filename = getExecutionPath() .. "/profiles/" .. _name .. ".xml";
local root = xml.open(filename);
local elements = root:getElements();
local loadOptions = function(node)
local elements = node:getElements();
for i,v in pairs(elements) do
settings.profile.options[v:getAttribute("name")] = v:getAttribute("value");
end
end
local loadHotkeys = function(node)
local elements = node:getElements();
for i,v in pairs(elements) do
settings.profile.hotkeys[v:getAttribute("name")] = {};
settings.profile.hotkeys[v:getAttribute("name")].key = key[v:getAttribute("key")];
settings.profile.hotkeys[v:getAttribute("name")].modifier = key[v:getAttribute("modifier")];
if( key[v:getAttribute("key")] == nil ) then
local err = sprintf("Profile error: Please set a valid key for "..
"hotkey %s in your profile file \'%s.xml\'.", tostring(v:getAttribute("name")), _name );
error(err, 0);
end
check_double_key_settings( v:getAttribute("name"), v:getAttribute("key"), v:getAttribute("modifier") );
end
end
local loadonLoadEvent = function(node)
local luaCode = tostring(node:getValue());
if( string.len(luaCode) > 0 and string.find(luaCode, "%w") ) then
settings.profile.events.onLoad = loadstring(luaCode);
if( type(settings.profile.events.onLoad) ~= "function" ) then
settings.profile.events.onLoad = nil;
end;
end
end
local loadOnDeathEvent = function(node)
local luaCode = tostring(node:getValue());
if( string.len(luaCode) > 0 and string.find(luaCode, "%w") ) then
settings.profile.events.onDeath = loadstring(luaCode);
if( type(settings.profile.events.onDeath) ~= "function" ) then
settings.profile.events.onDeath = nil;
end;
end
end
local loadOnLeaveCombatEvent = function(node)
local luaCode = tostring(node:getValue());
if( string.len(luaCode) > 0 and string.find(luaCode, "%w") ) then
settings.profile.events.onLeaveCombat = loadstring(luaCode);
if( type(settings.profile.events.onLeaveCombat) ~= "function" ) then
settings.profile.events.onLeaveCombat = nil;
end;
end
end
local loadOnSkillCastEvent = function(node)
local luaCode = tostring(node:getValue());
if( string.len(luaCode) > 0 and string.find(luaCode, "%w") ) then
settings.profile.events.onSkillCast = loadstring(luaCode);
if( type(settings.profile.events.onSkillCast) ~= "function" ) then
settings.profile.events.onSkillCast = nil;
end;
end
end
local skillSort = function(tab1, tab2)
if( tab2.priority < tab1.priority ) then
return true;
end;
return false;
end
local loadSkills = function(node)
local elements = node:getElements();
for i,v in pairs(elements) do
local name, hotkey, modifier, level;
name = v:getAttribute("name");
hotkey = key[v:getAttribute("hotkey")];
modifier = key[v:getAttribute("modifier")];
level = v:getAttribute("level");
check_double_key_settings( v:getAttribute("name"), v:getAttribute("hotkey") );
-- Over-ride attributes
local priority, maxhpper, inbattle, pullonly, maxuse
priority = v:getAttribute("priority");
maxhpper = tonumber(v:getAttribute("hpper"));
inbattle = v:getAttribute("inbattle");
pullonly = v:getAttribute("pullonly");
maxuse = tonumber(v:getAttribute("maxuse"));
-- check if 'wrong' options are set
if( v:getAttribute("mana") or
v:getAttribute("manainc") or
v:getAttribute("rage") or
v:getAttribute("energy") or
v:getAttribute("concentration") or
v:getAttribute("range") or
v:getAttribute("cooldown") or
v:getAttribute("minrange") or
v:getAttribute("type") or
v:getAttribute("target") or
v:getAttribute("casttime") ) then
cprintf(cli.yellow, "The options \'mana\', \'manainc\', \'rage\', "..
"\'energy\', \'concentration\', \'range\', "..
"\'cooldown\', \'minrange\', \'type\', \'target\' and \'casttime\' "..
"are no valid options for your skill \'%s\' in your profile \'%s.xml\'. "..
"Please delete them and restart!\n", name, _name);
error("Bot finished due of errors above.\n", 0);
end;
if( v:getAttribute("modifier") ) then
cprintf(cli.yellow, "The options \'modifier\' "..
"for your skill \'%s\' in your profile \'%s.xml\' "..
"is not supported at the moment. "..
"Please delete it and restart!\n", name, _name);
error("Bot finished due of errors above.\n", 0);
end;
if( name == nil) then
cprintf(cli.yellow, "You defined an \'empty\' skill name in "..
"your profile \'%s.xml\'. Please delete or correct "..
"that line!\n", _name);
error("Bot finished due of errors above.\n", 0);
end;
if( inbattle ~= nil ) then
if( inbattle == "true" or
inbattle == true ) then
inbattle = true;
elseif( inbattle == "false" or
inbattle == false ) then
inbattle = false;
else
cprintf(cli.yellow, "You defined an wrong option inbattle=\'%s\' at skill %s in "..
"your profile \'%s.xml\'. Please delete or correct "..
"that line!\n", inbattle, name, _name);
error("Bot finished due of errors above.\n", 0);
end;
end
if( pullonly ~= nil ) then
if( pullonly == "true" or
pullonly == true ) then
pullonly = true;
else
cprintf(cli.yellow, "You defined an wrong option pullonly=\'%s\' at skill %s in "..
"your profile \'%s.xml\'. Only \'true\' is possible. Please delete or correct "..
"that line!\n", pullonly, name, _name);
error("Bot finished due of errors above.\n", 0);
end;
end
if( level == nil or level < 1 ) then
level = 1;
end
local baseskill = database.skills[name];
if( not baseskill ) then
local err = sprintf("ERROR: \'%s\' is not defined in the database!", name);
error(err, 0);
end
local tmp = CSkill(database.skills[name]);
tmp.hotkey = hotkey;
tmp.modifier = modifier;
tmp.Level = level;
if( toggleable ) then tmp.Toggleable = toggleable; end;
if( priority ) then tmp.priority = priority; end
if( maxhpper ) then tmp.MaxHpPer = maxhpper; end;
if( inbattle ~= nil ) then tmp.InBattle = inbattle; end;
if( pullonly == true ) then tmp.pullonly = pullonly; end;
if( maxuse ) then tmp.maxuse = maxuse; end;
table.insert(settings.profile.skills, tmp);
end
table.sort(settings.profile.skills, skillSort);
end
local loadFriends = function(node)
local elements = node:getElements();
for i,v in pairs(elements) do
local name = v:getAttribute("name");
table.insert(settings.profile.friends, name);
end
end
local hf_temp = _name; -- remember profile name shortly
for i,v in pairs(elements) do
local name = v:getName();
if( string.lower(name) == "options" ) then
loadOptions(v);
elseif( string.lower(name) == "hotkeys" ) then
loadHotkeys(v);
elseif( string.lower(name) == "skills" ) then
loadSkills(v);
elseif( string.lower(name) == "friends" ) then
loadFriends(v);
elseif( string.lower(name) == "onLoad" ) then
loadonLoadEvent(v);
elseif( string.lower(name) == "ondeath" ) then
loadOnDeathEvent(v);
elseif( string.lower(name) == "onleavecombat" ) then
loadOnLeaveCombatEvent(v);
elseif( string.lower(name) == "onskillcast" ) then
loadOnSkillCastEvent(v);
elseif( string.lower(name) == "skills_warrior" and
player.Class1 == CLASS_WARRIOR ) then
loadSkills(v);
elseif( string.lower(name) == "skills_scout" and
player.Class1 == CLASS_SCOUT ) then
loadSkills(v);
elseif( string.lower(name) == "skills_rogue" and
player.Class1 == CLASS_ROGUE ) then
loadSkills(v);
elseif( string.lower(name) == "skills_mage" and
player.Class1 == CLASS_MAGE ) then
loadSkills(v);
elseif( string.lower(name) == "skills_priest" and
player.Class1 == CLASS_PRIEST ) then
loadSkills(v);
elseif( string.lower(name) == "skills_knight" and
player.Class1 == CLASS_KNIGHT ) then
loadSkills(v);
elseif( string.lower(name) == "skills_runedancer" and
player.Class1 == CLASS_RUNEDANCER ) then
loadSkills(v);
elseif( string.lower(name) == "skills_druid" and
player.Class1 == CLASS_DRUID ) then
loadSkills(v);
else -- warning for other stuff and misspellings
if ( string.lower(name) ~= "skills_warrior" and
string.lower(name) ~= "skills_scout" and
string.lower(name) ~= "skills_rogue" and
string.lower(name) ~= "skills_mage" and
string.lower(name) ~= "skills_priest" and
string.lower(name) ~= "skills_knight" and
string.lower(name) ~= "skills_runedancer" and
string.lower(name) ~= "skills_druid" ) then
cprintf(cli.yellow, tostring(language[60]), string.lower(tostring(name)),
tostring(hf_temp));
end;
end
end
function checkProfileHotkeys(name)
if( not settings.profile.hotkeys[name] ) then
error("ERROR: Hotkey not set for this profile: " ..name, 0);
end
end
-- Check to make sure everything important is set
checkProfileHotkeys("ATTACK");
-- default combat type if not in profile defined
if( settings.profile.options.COMBAT_TYPE ~= "ranged" and
settings.profile.options.COMBAT_TYPE ~= "melee" ) then
if( player.Class1 == CLASS_WARRIOR or
player.Class1 == CLASS_ROGUE or
-- player.Class1 == CLASS_RUNEDANCER or
player.Class1 == CLASS_KNIGHT ) then
settings.profile.options.COMBAT_TYPE = "melee";
elseif(
player.Class1 == CLASS_PRIEST or
player.Class1 == CLASS_SCOUT or
-- player.Class1 == CLASS_DRUID or
player.Class1 == CLASS_MAGE ) then
settings.profile.options.COMBAT_TYPE = "ranged";
else
error("undefined player.Class1 in settings.lua", 0);
end;
end
end
Re: Bad argument #1 to getkeyname
Right.at the very tippity top in green text...it does say that it read my bindings text...and thanks,i forgot it was in my documents folder.d003232 wrote:The bindings.txt is in your 'My Documents/Runes of Magic' folder. And you suppress evidence material ! There must be some green message at the begin of the MM protocal where the bot says, that he found and reads your bindings.txtSuffering wrote:bindings txt:And i actually had my Q button unbinded so i could use this as my ventrilo talk button.would this interfere with the bot?Code: Select all
i have no bindings.txt in my RoM folder.
And there is no rotate left button. I suppose you use your mouse You have ingame to assign one.
Re: Bad argument #1 to getkeyname
Due to technical reasons, for harversting, your RoM window has to be in the foreground.Suffering wrote:Yet another problem.My bot doesn't search for anything at its harvest points.Heres my harvest xml file
The RoM Bot Online Wiki needs your help!
Re: Bad argument #1 to getkeyname
It is in my foreground and i'v already figured this out.I'v been using this bot for a week or two so far.d003232 wrote:Due to technical reasons, for harversting, your RoM window has to be in the foreground.Suffering wrote:Yet another problem.My bot doesn't search for anything at its harvest points.Heres my harvest xml file
Re: Bad argument #1 to getkeyname
It just stands there for half a second like it just scanned very fast,then it goes to the next one.my mouse doesn't move an inch.And if i hover my mouse over a harvest node,it just stands there like a retard staring at titties for the first time.
Re: Bad argument #1 to getkeyname
I was already before wondering about yourSuffering wrote:It just stands there for half a second like it just scanned very fast,then it goes to the next one.my mouse doesn't move an inch.And if i hover my mouse over a harvest node,it just stands there like a retard staring at titties for the first time.
Code: Select all
RoM windows size is 0x0 upper left corner -32000,-32000
The RoM Bot Online Wiki needs your help!
Re: Bad argument #1 to getkeyname
No,i only got that left corner -32000 -3200 0x0 when i get errors.When the bot works it says:d003232 wrote:I was already before wondering about yourSuffering wrote:It just stands there for half a second like it just scanned very fast,then it goes to the next one.my mouse doesn't move an inch.And if i hover my mouse over a harvest node,it just stands there like a retard staring at titties for the first time.Do you have some special configuration with multiple screens or so?Code: Select all
RoM windows size is 0x0 upper left corner -32000,-32000
RoM windows size is 1270x946, uppder left corner at 4,23
Re: Bad argument #1 to getkeyname
Ok. Then I don't have any glue. I'm just now harversing without any problems. The bot is scaning and harvesting. Perhaps your settings are to fast?? Here are my individual settings for harvesting:Suffering wrote:No,i only got that left corner -32000 -3200 0x0 when i get errors.When the bot works it says:
RoM windows size is 1270x946, uppder left corner at 4,23
Code: Select all
<option name="HARVEST_SCAN_WIDTH" value="15" />
<option name="HARVEST_SCAN_HEIGHT" value="10" />
<option name="HARVEST_SCAN_STEPSIZE" value="22" />
<option name="HARVEST_SCAN_TOPDOWN" value="false" />
<option name="HARVEST_SCAN_YREST" value="7" />
The RoM Bot Online Wiki needs your help!
Re: Bad argument #1 to getkeyname
No dice,I think it has to do with something about it not being enabled.d003232 wrote:Ok. Then I don't have any glue. I'm just now harversing without any problems. The bot is scaning and harvesting. Perhaps your settings are to fast?? Here are my individual settings for harvesting:Suffering wrote:No,i only got that left corner -32000 -3200 0x0 when i get errors.When the bot works it says:
RoM windows size is 1270x946, uppder left corner at 4,23You could play around with the yrest value.Code: Select all
<option name="HARVEST_SCAN_WIDTH" value="15" /> <option name="HARVEST_SCAN_HEIGHT" value="10" /> <option name="HARVEST_SCAN_STEPSIZE" value="22" /> <option name="HARVEST_SCAN_TOPDOWN" value="false" /> <option name="HARVEST_SCAN_YREST" value="7" />
Re: Bad argument #1 to getkeyname
Though when i do put it at 100,or even 1000,it stands there as if the mouse were scanning.But it isn't moving.Any more ideas?
Re: Bad argument #1 to getkeyname
No dice,I think it has to do with something about it not being enabled.[/quote]There is nothing to enable. Only the player:harvest(); within the waypoints. Amd your move is not moving? No scan? And you are surely using your harvesting waypoint path with the commands within?Suffering wrote:[/code]You could play around with the yrest value.
The RoM Bot Online Wiki needs your help!
Re: Bad argument #1 to getkeyname
There is nothing to enable. Only the player:harvest(); within the waypoints. Amd your move is not moving? No scan? And you are surely using your harvesting waypoint path with the commands within?[/quote]d003232 wrote:No dice,I think it has to do with something about it not being enabled.Suffering wrote:[/code]You could play around with the yrest value.
My mouse is not moving,no scan,i posted my waypoint's XML file up there ^
l
l
l
l
l
l
l
l
Who is online
Users browsing this forum: Ahrefs [Bot] and 0 guests