-
KillerTHC
- Posts: 63
- Joined: Tue May 25, 2010 8:49 pm
#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
-
Administrator
- Site Admin
- Posts: 5313
- Joined: Sat Jan 05, 2008 4:21 pm
#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
#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
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
-
Administrator
- Site Admin
- Posts: 5313
- Joined: Sat Jan 05, 2008 4:21 pm
#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
#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
Who is online
Users browsing this forum: No registered users and 10 guests