Bad argument #1 to getkeyname

Runes of Magic/Radiant Arcana (http://www.runesofmagic.com)
Message
Author
Suffering
Posts: 34
Joined: Wed Aug 19, 2009 9:14 pm

Re: Bad argument #1 to getkeyname

#21 Post by Suffering » Thu Aug 20, 2009 6:17 pm

d003232 wrote:You are a good tester ... with your profile :-)

Just make a little correction at your seetings.lua line 345/346

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 );
I should be '_name' instead of 'name'. It will be in the SVN after I have the other stuff finished.
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
Posts: 1252
Joined: Wed Jun 03, 2009 4:27 pm

Re: Bad argument #1 to getkeyname

#22 Post by d003232 » Thu Aug 20, 2009 6:27 pm

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 SVN 196 is now commited. It should now correct check your profile and show you the error without having an error.
The RoM Bot Online Wiki needs your help!

Suffering
Posts: 34
Joined: Wed Aug 19, 2009 9:14 pm

Re: Bad argument #1 to getkeyname

#23 Post by Suffering » Thu Aug 20, 2009 6:31 pm

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:

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

d003232
Posts: 1252
Joined: Wed Jun 03, 2009 4:27 pm

Re: Bad argument #1 to getkeyname

#24 Post by d003232 » Thu Aug 20, 2009 6:37 pm

Suffering 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:
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.txt
The RoM Bot Online Wiki needs your help!

Suffering
Posts: 34
Joined: Wed Aug 19, 2009 9:14 pm

Re: Bad argument #1 to getkeyname

#25 Post by Suffering » Thu Aug 20, 2009 6:43 pm

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:

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>
bindings txt:

Code: Select all

i have no bindings.txt in my RoM folder.
And i actually had my Q button unbinded so i could use this as my ventrilo talk button.would this interfere with the bot?

Suffering
Posts: 34
Joined: Wed Aug 19, 2009 9:14 pm

Re: Bad argument #1 to getkeyname

#26 Post by Suffering » Thu Aug 20, 2009 6:46 pm

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.

d003232
Posts: 1252
Joined: Wed Jun 03, 2009 4:27 pm

Re: Bad argument #1 to getkeyname

#27 Post by d003232 » Thu Aug 20, 2009 6:48 pm

Suffering wrote:bindings txt:

Code: Select all

i have no bindings.txt in my RoM folder.
And i actually had my Q button unbinded so i could use this as my ventrilo talk button.would this interfere with the bot?
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.txt

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!

d003232
Posts: 1252
Joined: Wed Jun 03, 2009 4:27 pm

Re: Bad argument #1 to getkeyname

#28 Post by d003232 » Thu Aug 20, 2009 6:49 pm

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.
Thx for your endurance and patience. We can now to the checks a little better to avoid misconfigurations in the future.
The RoM Bot Online Wiki needs your help!

Suffering
Posts: 34
Joined: Wed Aug 19, 2009 9:14 pm

Re: Bad argument #1 to getkeyname

#29 Post by Suffering » Thu Aug 20, 2009 6:55 pm

Yet another problem.My bot doesn't search for anything at its harvest points.Heres my harvest xml file

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>
hmmmm heres my profile:

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>
my settings.lua

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

Suffering
Posts: 34
Joined: Wed Aug 19, 2009 9:14 pm

Re: Bad argument #1 to getkeyname

#30 Post by Suffering » Thu Aug 20, 2009 7:01 pm

d003232 wrote:
Suffering wrote:bindings txt:

Code: Select all

i have no bindings.txt in my RoM folder.
And i actually had my Q button unbinded so i could use this as my ventrilo talk button.would this interfere with the bot?
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.txt

And there is no rotate left button. I suppose you use your mouse :-) You have ingame to assign one.
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
Posts: 1252
Joined: Wed Jun 03, 2009 4:27 pm

Re: Bad argument #1 to getkeyname

#31 Post by d003232 » Thu Aug 20, 2009 7:06 pm

Suffering wrote:Yet another problem.My bot doesn't search for anything at its harvest points.Heres my harvest xml file
Due to technical reasons, for harversting, your RoM window has to be in the foreground.
The RoM Bot Online Wiki needs your help!

Suffering
Posts: 34
Joined: Wed Aug 19, 2009 9:14 pm

Re: Bad argument #1 to getkeyname

#32 Post by Suffering » Thu Aug 20, 2009 7:10 pm

d003232 wrote:
Suffering wrote:Yet another problem.My bot doesn't search for anything at its harvest points.Heres my harvest xml file
Due to technical reasons, for harversting, your RoM window has to be in the foreground.
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.

Suffering
Posts: 34
Joined: Wed Aug 19, 2009 9:14 pm

Re: Bad argument #1 to getkeyname

#33 Post by Suffering » Thu Aug 20, 2009 7:11 pm

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.

d003232
Posts: 1252
Joined: Wed Jun 03, 2009 4:27 pm

Re: Bad argument #1 to getkeyname

#34 Post by d003232 » Thu Aug 20, 2009 7:21 pm

Suffering 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.
I was already before wondering about your

Code: Select all

RoM windows size is 0x0 upper left corner -32000,-32000
Do you have some special configuration with multiple screens or so?
The RoM Bot Online Wiki needs your help!

Suffering
Posts: 34
Joined: Wed Aug 19, 2009 9:14 pm

Re: Bad argument #1 to getkeyname

#35 Post by Suffering » Thu Aug 20, 2009 7:23 pm

d003232 wrote:
Suffering 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.
I was already before wondering about your

Code: Select all

RoM windows size is 0x0 upper left corner -32000,-32000
Do you have some special configuration with multiple screens or so?
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

d003232
Posts: 1252
Joined: Wed Jun 03, 2009 4:27 pm

Re: Bad argument #1 to getkeyname

#36 Post by d003232 » Thu Aug 20, 2009 7:25 pm

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
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:

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" />	
You could play around with the yrest value.
The RoM Bot Online Wiki needs your help!

Suffering
Posts: 34
Joined: Wed Aug 19, 2009 9:14 pm

Re: Bad argument #1 to getkeyname

#37 Post by Suffering » Thu Aug 20, 2009 7:28 pm

d003232 wrote:
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
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:

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" />	
You could play around with the yrest value.
No dice,I think it has to do with something about it not being enabled.

Suffering
Posts: 34
Joined: Wed Aug 19, 2009 9:14 pm

Re: Bad argument #1 to getkeyname

#38 Post by Suffering » Thu Aug 20, 2009 7:30 pm

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?

d003232
Posts: 1252
Joined: Wed Jun 03, 2009 4:27 pm

Re: Bad argument #1 to getkeyname

#39 Post by d003232 » Thu Aug 20, 2009 7:32 pm

Suffering wrote:[/code]You could play around with the yrest value.
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?
The RoM Bot Online Wiki needs your help!

Suffering
Posts: 34
Joined: Wed Aug 19, 2009 9:14 pm

Re: Bad argument #1 to getkeyname

#40 Post by Suffering » Thu Aug 20, 2009 7:34 pm

d003232 wrote:
Suffering wrote:[/code]You could play around with the yrest value.
No dice,I think it has to do with something about it not being enabled.
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]
My mouse is not moving,no scan,i posted my waypoint's XML file up there ^
l
l
l
l
l
l
l
l

Post Reply

Who is online

Users browsing this forum: Google [Bot] and 1 guest