Improved loot method

Runes of Magic/Radiant Arcana (http://www.runesofmagic.com)
Post Reply
Message
Author
KillerTHC
Posts: 63
Joined: Tue May 25, 2010 8:49 pm

Improved loot method

#1 Post by KillerTHC » Sat Jul 24, 2010 5:34 pm

Well I made a new and improved loot method the only problem is it doesn't loot! It will walk up to the dead mob and then just move on to the next mob to fight. lootNearest is the method to actually loot where as findLoot locates dead mobs to loot.

Code: Select all

function findLoot(_id, ignore)
	ignore = ignore or 0;
	local bestTarget = nil;
	local bestScore = 0;
	local obj = nil;
	local objectList = CObjectList();
	objectList:update();
	addMessage("Looking for lootable mobs");
	-- The 'max' values that each scoring sub-part uses
	local SCORE_DISTANCE = 60;      -- closer = more score; actually score will usually be less than half
	local SCORE_DEAD = 100; -- dead = possibly lootable
	
	for i = 0,objectList:size() do
		obj = objectList:getObject(i);

		if( obj ~= nil ) then
			if( obj.Type == PT_MONSTER and (_id == obj.Id or _id == nil) and obj.Address ~= ignore) then
				local dist = distance(player.X, player.Z, obj.X, obj.Z);
				local pawn = CPawn(obj.Address);
				
				if( distance(player.X, player.Z, obj.X, obj.Z ) < settings.profile.options.MAX_TARGET_DIST and
				(obj.Address ~= player.Address)) then
					local currentScore = 0;
					currentScore = currentScore + ( (settings.profile.options.MAX_TARGET_DIST - dist) / settings.profile.options.MAX_TARGET_DIST * SCORE_DISTANCE );
					
					pawn:update();
					if( pawn.Alive == false ) then
						currentScore = currentScore + SCORE_DEAD;
					else	
						currentScore = 0;
					end
					
					if( bestTarget == nil ) then
						addMessage("Found lootable pawn named "..pawn.Name.."\n");
						printf("Found lootable pawn named "..pawn.Name.."\n");
						bestTarget = obj;
						bestScore = currentScore;
					elseif( currentScore > bestScore ) then
						addMessage("Found better lootable pawn named "..pawn.Name.."\n");
						printf("Found better lootable pawn named "..pawn.Name.."\n");
						bestTarget = obj;
						bestScore = currentScore;
					end
				end
			end
		end
	end

	if( bestTarget ) then
		return CPawn(bestTarget.Address);
	else
		return nil;
	end
end

function lootNearest()
	local nearestLootable = nil;
	
	nearestLootable = findLoot();
	
	if( nearestLootable and nearestLootable.Lootable ) then
		success, reason = player:moveTo(nearestLootable, true);
		if( success ) then
			addMessage("Successfully walked to the corpse\n");
			printf("Successfully walked to the corpse\n");
			if( player.LastTarget ~= nearestLootable.Address ) then
				player.TargetPtr = nearestLootable.Address;
			end
			addMessage("Player Target = "..player.TargetPtr.."\n".."Nearest lootable address = "..nearestLootable.Address.."\n");
			printf("Player Target = "..player.TargetPtr.."\n".."Nearest lootable address = "..nearestLootable.Address.."\n");
			RoMScript("UseSkill(1,1);");
			yrest(250);
			RoMScript("BootyFrame:Hide()");
		end
	end
end

User avatar
Administrator
Site Admin
Posts: 5313
Joined: Sat Jan 05, 2008 4:21 pm

Re: Improved loot method

#2 Post by Administrator » Sat Jul 24, 2010 6:55 pm

Why are you using a scoring method on whether it's dead or not? You should just be checking if target.Lootable is true, otherwise don't loot it. Doesn't mater. I'll be fixing this up as soon as we get the inventory stuff worked out.

Anyways, I bet the problem is because you used a semicolon in RoMScript, which is generating a syntax error.

KillerTHC
Posts: 63
Joined: Tue May 25, 2010 8:49 pm

Re: Improved loot method

#3 Post by KillerTHC » Sat Jul 24, 2010 7:03 pm

I figured it out, you cant just say Player.TargetPtr = a new target and expect it to work. You have to actually change the memory in the game. I have an is lootable check in the second method that works very well.

Updated script that works :D

Code: Select all

function findLoot(_id, ignore)
	ignore = ignore or 0;
	local bestTarget = nil;
	local bestScore = 0;
	local obj = nil;
	local objectList = CObjectList();
	objectList:update();
	addMessage("Looking for lootable mobs");
	-- The 'max' values that each scoring sub-part uses
	local SCORE_DISTANCE = 60;      -- closer = more score; actually score will usually be less than half
	
	for i = 0,objectList:size() do
		obj = objectList:getObject(i);

		if( obj ~= nil ) then
			if( obj.Type == PT_MONSTER and (_id == obj.Id or _id == nil) and obj.Address ~= ignore) then
				local dist = distance(player.X, player.Z, obj.X, obj.Z);
				local pawn = CPawn(obj.Address);
				
				if( distance(player.X, player.Z, obj.X, obj.Z ) < settings.profile.options.MAX_TARGET_DIST and
				(obj.Address ~= player.Address)) then
					local currentScore = 0;
					currentScore = currentScore + ( (settings.profile.options.MAX_TARGET_DIST - dist) / settings.profile.options.MAX_TARGET_DIST * SCORE_DISTANCE );
					
					pawn:update();
					if( pawn.Alive == true ) then
						currentScore = 0;
					end
					
					if( bestTarget == nil ) then
						addMessage("Found lootable pawn named "..pawn.Name.."\n");
						printf("Found lootable pawn named "..pawn.Name.."\n");
						bestTarget = obj;
						bestScore = currentScore;
					elseif( currentScore > bestScore ) then
						addMessage("Found better lootable pawn named "..pawn.Name.."\n");
						printf("Found better lootable pawn named "..pawn.Name.."\n");
						bestTarget = obj;
						bestScore = currentScore;
					end
				end
			end
		end
	end

	if( bestTarget ) then
		return CPawn(bestTarget.Address);
	else
		return nil;
	end
end

function lootNearest()
	local nearestLootable = nil;
	
	nearestLootable = findLoot();
	
	if( nearestLootable and nearestLootable.Lootable ) then
		success, reason = player:moveTo(nearestLootable, true);
		if( success ) then
			addMessage("Successfully walked to the corpse\n");
			printf("Successfully walked to the corpse\n");
			if( player.LastTarget ~= nearestLootable.Address ) then
				memoryWriteInt(getProc(), player.Address + addresses.pawnTargetPtr_offset, nearestLootable.Address);
			end
			addMessage("Player Target = "..player.TargetPtr.."\n".."Nearest lootable address = "..nearestLootable.Address.."\n");
			printf("Player Target = "..player.TargetPtr.."\n".."Nearest lootable address = "..nearestLootable.Address.."\n");
			addMessage("Dead Mob Name: "..nearestLootable.Name.."\n");
			addMessage("Dead Mob is Lootable?: "..tostring(nearestLootable.Lootable).."\n");
			addMessage("Dead Mob Type: "..nearestLootable.Type.."\n");
			addMessage("Dead Mob ID: "..nearestLootable.Id.."\n");
			
			RoMScript("UseSkill(1,1)");
			yrest(1200);
			RoMScript("BootyFrame:Hide()");
		end
	end
end

User avatar
Administrator
Site Admin
Posts: 5313
Joined: Sat Jan 05, 2008 4:21 pm

Re: Improved loot method

#4 Post by Administrator » Sat Jul 24, 2010 7:11 pm

Just an FYI, you can use self:target(address or pawn here) now (assuming this is being called within the player class).

KillerTHC
Posts: 63
Joined: Tue May 25, 2010 8:49 pm

Re: Improved loot method

#5 Post by KillerTHC » Sat Jul 24, 2010 7:22 pm

Wow I don't know how I missed that lol. I updated it to be able to loot multiple mobs and cleaned up the code a bit.

Code: Select all

function findLoot(_id, ignore)
	ignore = ignore or 0;
	local bestTarget = nil;
	local bestScore = 0;
	local obj = nil;
	local objectList = CObjectList();
	objectList:update();

	-- The 'max' values that each scoring sub-part uses
	local SCORE_DISTANCE = 60;      -- closer = more score; actually score will usually be less than half
	
	for i = 0,objectList:size() do
		obj = objectList:getObject(i);

		if( obj ~= nil ) then
			if( obj.Type == PT_MONSTER and (_id == obj.Id or _id == nil) and obj.Address ~= ignore) then
				local dist = distance(player.X, player.Z, obj.X, obj.Z);
				local pawn = CPawn(obj.Address);
				
				if( distance(player.X, player.Z, obj.X, obj.Z ) < settings.profile.options.MAX_TARGET_DIST and
				(obj.Address ~= player.Address)) then
					local currentScore = 0;
					currentScore = currentScore + ( (settings.profile.options.MAX_TARGET_DIST - dist) / settings.profile.options.MAX_TARGET_DIST * SCORE_DISTANCE );
					
					pawn:update();
					if( pawn.Alive == true ) then
						currentScore = 0;
					end
					
					if( bestTarget == nil and pawn.Lootable ) then
						bestTarget = obj;
						bestScore = currentScore;
					elseif( currentScore > bestScore and pawn.Lootable ) then
						bestTarget = obj;
						bestScore = currentScore;
					end
				end
			end
		end
	end

	if( bestTarget ) then
		return CPawn(bestTarget.Address);
	else
		return nil;
	end
end

function lootNearest()
	local nearestLootable = nil;
	local trys = 0;
	
	nearestLootable = findLoot();
	trys = trys + 1;
	
	while(true) do
		if( nearestLootable ) then
			success, reason = player:moveTo(nearestLootable, true);
			if( success and not player.Battling ) then
				player:target(nearestLootable);
				RoMScript("UseSkill(1,1)");
				yrest(1200);
				RoMScript("BootyFrame:Hide()");
				player:clearTarget();
				
				if( trys < 3 ) then
					nearestLootable = findLoot();
					trys = trys + 1;
				else 
					break;
				end
			elseif( not success ) then
				if( trys < 3 ) then
					nearestLootable = findLoot();
					trys = trys + 1;
				else 
					break;
				end
			elseif( player.Battling ) then
				break;
			end
		else
			if( trys < 3 ) then
				nearestLootable = findLoot();
				trys = trys + 1;
			else 
				break;
			end
		end
	end
end

Post Reply

Who is online

Users browsing this forum: No registered users and 10 guests