Sorry, about your loss, but I find it surprising you would risk all dem pixels without reading some code first…..and yes, it is designed to pick your items up before exiting…just for curiosity, what script were you using ?
Jerry T, what do you suggest we change ? :)
//Special thanks to bolshak25.
const
LEO_GRAVESTONE_MIDDLE = 12718;
LEO_CASKET1 = 12721;
LEO_CASKET2 = 12722;
LEO_CASKET3 = 12723;
LEO_CASKET4 = 12724;
LEO_CASKET5 = 12725;
LEO_EMPTY_GRAVE1 = 12726;
LEO_EMPTY_GRAVE2 = 12727;
LEO_EMPTY_GRAVE3 = 12728;
LEO_EMPTY_GRAVE4 = 12729;
LEO_EMPTY_GRAVE5 = 12730;
LEO_INVENTORY_CASKET1 = 7587;
LEO_INVENTORY_CASKET2 = 7588;
LEO_INVENTORY_CASKET3 = 7589;
LEO_INVENTORY_CASKET4 = 7590;
LEO_INVENTORY_CASKET5 = 7591;
LEO_FLOWERPOTID = 7608;
LEO_PICKAXEID = 7607;
LEO_CHEFHATID = 7601;
LEO_HATCHETID = 7603;
LEO_SHEARSID = 7610;
LEO_STONE_HATCHETID = 7614;
LEO_STONE_CHEFHATID = 7615;
LEO_STONE_PICKAXEID = 7616;
LEO_STONE_SHEARSID = 7617;
LEO_STONE_FLOWERPOTID = 7618;
{*******************************************************************************
function R_LeoComponentID (ParentI, ChildI : Integer) : Integer;
By: Cstrike
Description: This function wasn't in the core, so I made my own.
*******************************************************************************}
function R_LeoComponentID (ParentI, ChildI : Integer): Integer;
var
Child: Integer;
begin
Child := GetInterface(ParentI, ChildI);
Result := SmartGetFieldInt(Child, hook_interface_GetID);
SmartFreeObject(Child);
end;
{*******************************************************************************
procedure R_LeoInvDecrease (amount, timeout : Integer);
By: Cstrike
Description: Function used mainly for seeing when we have put the casket in the
grave.
*******************************************************************************}
procedure R_LeoInvDecrease(Amount, Timeout: Integer);
var
T, Count: Integer;
begin
If not LoggedIn then
Exit;
Count := R_InvCount;
MarkTime(T);
repeat
Wait(50+random(25));
until(TimeFromMark(t) > Amount)or(Count < R_InvCount)
Wait(4000+random(2500)); // More human?
end;
{*******************************************************************************
function R_InLeo : Boolean;
By: Cstrike
Description: Returns True if in Gravedigger.
*******************************************************************************}
function R_InLeo: Boolean;
begin
Result := ValidNPC('Leo');
end;
{*******************************************************************************
procedure R_LeoWalkToCenter;
By: Cstrike
Description: Moves us above middle grave so everything is in sight.
*******************************************************************************}
procedure R_LeoWalkToCenter;
var
TP: TPoint;
NPCs : TNPCArray;
LeoTile : TTile;
begin
if not LoggedIn then
Exit;
NPCs := SortNPCs(GetAllNPCs(False));
LeoTile := NPCs[0].Tile;
TP := TileToMM(Tile(LeoTile.X, LeoTile.Y-5));
Mouse (TP.X, TP.Y, 1, 1, True);
if WaitToMove(3000) then
R_Flag;
end;
{*******************************************************************************
function R_TalkToLeoStart : Boolean;
By: Cstrike
Description: Talks to Leo at start (if we are already, proceeds normally).
*******************************************************************************}
function R_TalkToLeoStart: Boolean;
var
T, X, Y: Integer;
NPCs: TNPCArray;
TP: TPoint;
begin
Result := False;
if not LoggedIn then
Exit;
if (not ValidInterface(242)) and (not ValidInterface(241)) and (not ValidInterface(243)) and (not ValidInterface(64)) then
begin
NPCs := SortNPCs(GetAllNPCs(False));
if Not TileOnMS(NPCs[0].Tile, 0)then
R_LeoWalkToCenter;
TP := TileToMS (NPCs[0].Tile, 0);
Mouse(TP.X, TP.Y, 3, 3, False);
Wait(500+Random(500));
if ChooseOptionMulti(['Ta','-to'])then
begin
Wait(1000+Random(1000));
Flag;
R_Debug('Talked to leo', 'Leo');
end;
Wait(2500+random(1500));
end else
R_Debug('Leo is already chatting with us', 'Leo');
Wait(3000+random(2000)); // Stops lag at start up from screwing us over
MarkTime(T);
repeat
if (GetInterfaceText(242, 6) = 'Click here to continue')then
Mouse(303, 452, 72, 7, True);
if (GetInterfaceText(241, 5) = 'Click here to continue') or (GetInterfaceText(243, 7) = 'Click here to continue') or (GetInterfaceText(64, 5) = 'Click here to continue') then
begin
GetMousePos(X, Y);
Mouse(X, Y, 0, 0, True);
end;
if (ValidInterface(220)) then
Mouse(456, 44, 6, 6, True);
Wait(670+random(600));
if (not ValidInterface(242)) and (not ValidInterface(241)) and (not ValidInterface(243)) and (not ValidInterface(64)) and (not ValidInterface(220)) then
begin
R_Debug('Successfully done talking to leo', 'Leo');
Result := True;
Exit;
end;
until (TimeFromMark(t) > 30000)
R_Debug('Timeout talking to Leo at start', 'Leo');
end;
{*******************************************************************************
function R_LeoDropInv : TIntegerArray;
By: Cstrike
Description: Makes space by dropping items farthest down in your inventory.
result := [tile x dropped, tile y dropped (, item1 (, item2 (, item 3...];
*******************************************************************************}
function R_LeoDropInv: TIntegerArray;
var
i, arrPos: Integer;
myTile: TTile;
begin
if not LoggedIn then
Exit;
Result := [];
if R_InvCount > 23 then
begin
R_Debug('Making space for random', 'Leo');
arrPos := 2; // 0 is Tile.x, 1 is Tile.y, 2 is item1, 3 is item2...etc, we want to start filling at index w/ arrPos
SetArrayLength (result, (R_InvCount-23)+2); // If count is 25, then we have the first 2 as tile, last two as ID's
myTile := GetMyPos;
result[0] := myTile.x;
result[1] := myTile.y;
for i:=28 downto 1 do // If there is that 'destroy crap' for whatever, then this will probably skip it... thus downto 0
begin
if R_InvCount < 24 then
Exit;
if R_ItemSlotExists(i) then
begin
result[arrPos] := GetItemIDAt(i);
// R_DropItem(i);
Wait (900+random(350));
Inc(arrPos);
end;
end;
end else R_Debug('We have 5+ inventory spaces for the Leo random, proceeding...', 'Leo');
end;
{*******************************************************************************
procedure R_LeoRetrieveInv (TIA : TIntegerArray);
By: Cstrike
Description: If you dropped anything, picks it up.
*******************************************************************************}
procedure R_LeoRetrieveInv(TIA: TIntegerArray);
var
GIA: TGroundItemArray;
t: Integer;
TP: TPoint;
begin
if not LoggedIn then
Exit;
if (high(TIA) < 0) then
Exit;
GIA := []; // Failsafe
MarkTime(t);
R_Debug('Picking up items dropped', 'Leo');
if (high(TIA) < 2) then
Exit
else // No items to retrieve
begin
if not TileOnMS(Tile(TIA[0],TIA[1]), 0)then
WalkToTile (Tile(TIA[0],TIA[1]), 1, 0);
repeat
GIA := GetItemsAt(Tile(TIA[0],TIA[1]));
if high(GIA) > -1 then
begin
TP := TileToMS(Tile(TIA[0],TIA[1]), 0);
Mouse(TP.x, TP.y, 2, 2, True);
R_Flag;
end;
until (high(GIA) < 0) or (TimeFromMark(t) > 15000)
end;
GIA := []; // Need to blank this for a memory reason
TIA := []; // Blank TIA in case we fail and need to start fresh
end;
{*******************************************************************************
function R_LeoGraveTiles (i : Integer) : TTile;
By: Cstrike
Description: Returns grave tile positions relative to Leo. This can be revamped
in the future with objects.
*******************************************************************************}
function R_LeoGraveTiles (i : Integer): TTile;
var
NPCs : TNPCArray;
LeoTile : TTile;
begin
if not LoggedIn then
Exit;
Result := Tile(0,0); // Failsafe
NPCs := SortNPCs(GetAllNPCs(False));
LeoTile := NPCs[0].Tile;
case i of // BL, TL, BM, TR, Bottom Right [BR]
0: result := Tile(LeoTile.x-4,LeoTile.y-7);
1: result := Tile(LeoTile.x-2,LeoTile.y-4);
2: result := Tile(LeoTile.x-0,LeoTile.y-7);
3: result := Tile(LeoTile.x+2,LeoTile.y-4);
4: result := Tile(LeoTile.x+4,LeoTile.y-7);
end;
end;
{*******************************************************************************
function R_LeoGravestoneTiles (i : Integer) : TTile;
By: Cstrike
Description: Returns graveSTONE tile positions relative to Leo. This can be
revamped in the future with objects.
*******************************************************************************}
function R_LeoGravestoneTiles (i : Integer): TTile;
var
NPCs : TNPCArray;
LeoTile : TTile;
begin
if not LoggedIn then
Exit;
Result := Tile(0,0);
NPCs := SortNPCs(GetAllNPCs(False));
LeoTile := NPCs[0].Tile;
case i of // BL, TL, BM, TR, Bottom Right [BR]
0: result := Tile(LeoTile.x-4,LeoTile.y-5);
1: result := Tile(LeoTile.x-2,LeoTile.y-2);
2: result := Tile(LeoTile.x-0,LeoTile.y-5);
3: result := Tile(LeoTile.x+2,LeoTile.y-2);
4: result := Tile(LeoTile.x+4,LeoTile.y-5);
end;
end;
{*******************************************************************************
function R_GraveObjectCoffinCollect : Boolean;
By: Cstrike/mormonman
Description: Collects all the coffins. Returns True if successful.
*******************************************************************************}
function R_GraveObjectCoffinCollect: Boolean;
var
ObjCasket : TRSObject;
EmptyArr : TIntegerArray;
PickupTime, CasketTime, i, InviCount : Integer;
CurTile : TTile;
TP : TPoint;
begin
if not LoggedIn then
Exit;
Result := False;
EmptyArr := [LEO_EMPTY_GRAVE1, LEO_EMPTY_GRAVE2, LEO_EMPTY_GRAVE3,
LEO_EMPTY_GRAVE4, LEO_EMPTY_GRAVE5];
// Failsafe below
for i := 0 to 4 do
begin
CurTile := R_LeoGraveTiles(i);
ObjCasket := GetObjectAt(CurTile, OBJECT_TYPE_INTERACTABLE);
if ObjCasket.ID = EmptyArr[i] then
begin
R_Debug('Casket[' + ToStr(i) + '] already taken', 'Leo');
Continue;
end;
// Main part of script
SetAngle(True);
R_Debug('Grabbing Casket[' + ToStr(i) + ']', 'Leo');
MarkTime(CasketTime);
repeat
if not TileOnMS(ObjCasket.Tile, 0) then
R_LeoWalkToCenter;
TP := TileToMS (ObjCasket.Tile, 0);
Mouse (TP.x, TP.y, 2, 3, True);
InviCount := R_InvCount;
MarkTime(PickupTime);
repeat
Wait(250);
until (R_InvCount > InviCount) or (TimeFromMark(PickupTime) > 10000);
if not (TimeFromMark(PickupTime) > 10000) then Break;
until (TimeFromMark(CasketTime) > 30000);
end;
Result := (R_CountItemEx([LEO_INVENTORY_CASKET1, LEO_INVENTORY_CASKET2,
LEO_INVENTORY_CASKET3, LEO_INVENTORY_CASKET4,
LEO_INVENTORY_CASKET5]) = 5);
end;
{*******************************************************************************
function R_LeoFindCasket (name : String) : Integer;
By: Cstrike
Description: Searches for the name of what casketID matches the name you give it
*******************************************************************************}
function R_LeoFindCasket (name : String): Integer;
var
i, j, IDToFind : Integer;
begin
if not LoggedIn then
Exit;
Result := 0;
case name of
'flowerpot': IDToFind := LEO_FLOWERPOTID;
'pickaxe': IDToFind := LEO_PICKAXEID;
'chef hat': IDToFind := LEO_CHEFHATID;
'hatchet': IDToFind := LEO_HATCHETID;
'watertank': IDToFind := LEO_SHEARSID;
end;
for i:=LEO_INVENTORY_CASKET1 to LEO_INVENTORY_CASKET5 do
begin
R_ClickItemBy(i, True, 'open');
R_Debug('Checking Casket[' + ToStr(i) + ']', 'Leo');
Wait(2000+random(1500));
for j:=3 to 11 do // Search interfaces for ID to find
begin
Wait(50+random(50)); // More human like waiting
if (R_LeoComponentID (141, j) = IDToFind) then // 141 is the ID
begin
R_Debug('Found: ' + name + ' in Casket[' + ToStr(i) + ']', 'Leo');
Result := i;
Mouse(493, 27, 3, 3, True);
Wait(700+random(500));
Exit;
end;
end;
end;
end;
{*******************************************************************************
function R_LeoFindEmptyGrave : Integer;
By: mormonman
Description: Finds an empty grave and returns its gravestone number.
*******************************************************************************}
function R_LeoFindEmptyGrave: Integer;
var
EmptyArr: TIntegerArray;
obj: TRSObject;
i: Integer;
begin
Result := -1;
if not LoggedIn then
Exit;
EmptyArr := [LEO_EMPTY_GRAVE1, LEO_EMPTY_GRAVE2, LEO_EMPTY_GRAVE3,
LEO_EMPTY_GRAVE4, LEO_EMPTY_GRAVE5];
for i := 0 to 4 do
begin
obj := GetObjectAt(R_LeoGraveTiles(i), OBJECT_TYPE_INTERACTABLE);
if obj.ID = EmptyArr[i] then
begin
Result := i;
R_Debug('Empty Grave Index: ' + ToStr(i), 'Leo');
Exit;
end;
end;
end;
{*******************************************************************************
function R_LeoSolveGraves : Boolean;
By: Cstrike/mormonman
Description: This is the big procedure that solves the graves. False = failed.
*******************************************************************************}
function R_LeoSolveGraves : Boolean;
var
j, t, texID, CasketID, CurGrave, iTime : Integer;
GStoneTile : TTile;
TP : TPoint;
texName: String;
begin
Result := False;
if not LoggedIn then
Exit;
MarkTime(iTime);
repeat
CurGrave := R_LeoFindEmptyGrave;
if (CurGrave > -1) then
begin
R_Debug('Starting on grave[' +ToStr(CurGrave)+ ']', 'Leo');
GStoneTile := R_LeoGravestoneTiles(CurGrave);
if not TileOnMS(GStoneTile, 0) then
R_LeoWalkToCenter;
TP := TileToMS(GStoneTile, 0);
Mouse(TP.x, TP.y, 3, 3, True);
MarkTime(t);
repeat
Wait(500);
until(ValidInterface(143))or(TimeFromMark(t) > 10000);
Wait(1100+random(1100));
if ValidInterface(143) then
begin
for j:=0 to 3 do // Search the 3x3 item square
begin
texID := R_LeoComponentID(143, j);
texName := '';
case texID of
LEO_STONE_HATCHETID: texName := 'hatchet';
LEO_STONE_CHEFHATID: texName := 'chef hat';
LEO_STONE_PICKAXEID: texName := 'pickaxe';
LEO_STONE_SHEARSID: texName := 'watertank';
LEO_STONE_FLOWERPOTID: texName := 'flowerpot';
end;
if not (texName = '') then Break;
end;
R_Debug('Found: ' +texName+ ' model (ID Found: '+inttostr(texID)+')', 'Leo');
Mouse(491, 29, 3, 3, True);
Wait(100+random(500)); // Exits the model view
CasketID := R_LeoFindCasket(texName);
R_Debug('Casket ID found = '+inttostr(casketID), 'Leo');
if R_ClickItemBy(CasketID, false, 'use') then
begin
TP := TileToMS(Tile(GStoneTile.x, GStoneTile.y-1), 0);
Mouse (TP.x, TP.y, 3, 3, True);
R_LeoInvDecrease(1, 12000);
end;
end;
Wait(1000+Random(1000)); // More Wait here, must replace this later on
end else R_Debug('CurGrave is -1', 'Leo');
until (R_LeoFindEmptyGrave = -1) or (TimeFromMark(iTime) > 300000);//5 minutes to solve
Result := (TimeFromMark(iTime) < 300000) and LoggedIn
and (R_CountItemEx([LEO_INVENTORY_CASKET1, LEO_INVENTORY_CASKET2,
LEO_INVENTORY_CASKET3, LEO_INVENTORY_CASKET4, LEO_INVENTORY_CASKET5]) < 1);
end;
{*******************************************************************************
function R_TalkToLeoEnd : Boolean;
By: Cstrike
Description: Talks to Leo to solve the random. If we mess up, returns false.
*******************************************************************************}
function R_TalkToLeoEnd : Boolean;
var
t: Integer;
NPCs: TNPCArray;
TP: TPoint;
begin
Result := False;
if not LoggedIn then
Exit;
if (not ValidInterface(241)) and (not ValidInterface(64)) then
begin
NPCs := SortNPCs(GetAllNPCs(False));
if not TileOnMS(NPCs[0].Tile, 0) then
begin
WalkToTile(NPCs[0].Tile, 0, 0);
Wait(2000+Random(1000));
end;
TP := TileToMS (NPCs[0].Tile, 0);
Mouse(TP.x, TP.y, 3, 3, false);
Wait(500+random(500));
if ChooseOptionMulti(['Ta','-to']) then
begin
R_Debug('Talked to leo at end', 'Leo');
Wait(1000+Random(1000));
Flag;
end;
Wait(2500+random(1500));
end else R_Debug('Leo is already chatting with us', 'Leo');
Wait (3000+random(2000)); // Stops lag at start up from screwing us over
MarkTime(t);
repeat
if (GetInterfaceText(241, 5) = 'Click here to continue') or (GetInterfaceText(64, 5) = 'Click here to continue') then Mouse (303, 452, 72, 7, True);
Wait (670+random(600));
if (not ValidInterface(241)) and (not ValidInterface(64)) then
begin
R_Debug('Done chatting with Leo at end', 'Leo');
Result := True;
Exit;
end;
until (TimeFromMark(t) > 20000)
R_Debug('Timeout talking to Leo at end, result = false', 'Leo');
end;
{*******************************************************************************
function R_SolveLeo : Boolean;
By: Cstrike
Description: Attempts to solve the random.
*******************************************************************************}
function R_SolveLeo : Boolean;
var failsafe : Integer;
ItemDropData : TIntegerArray;
begin
result := false;
ItemDropData := []; // Failsafe
if R_InLeo then
begin
failsafe := 0;
repeat
R_Debug('Leo Phase 1: Talk to Leo at start', 'Leo');
if R_TalkToLeoStart then
begin
if ((R_InvCount - R_CountItemEx([LEO_INVENTORY_CASKET1,
LEO_INVENTORY_CASKET2,
LEO_INVENTORY_CASKET3,
LEO_INVENTORY_CASKET4,
LEO_INVENTORY_CASKET5])) > 23)then
ItemDropData := R_LeoDropInv; // Declared it here so it can pick it up later
R_Debug('Leo Phase 2: Collect graves', 'Leo');
if R_GraveObjectCoffinCollect then
begin
R_Debug('Leo Phase 3: Solve the graves', 'Leo');
if R_LeoSolveGraves then
begin
if (high(ItemDropData) < 0) then
R_LeoRetrieveInv (ItemDropData); // If we dropped something, now is the time to pick it up
R_Debug('Leo Phase 4: Talk to Leo at end', 'Leo');
if R_TalkToLeoEnd then
begin
Wait(3000+Random(2000));
result := True;
Exit;
end;
end else
begin
R_Debug('Failed solving graves', 'Leo');
if (high(ItemDropData) < 0) then
R_LeoRetrieveInv (ItemDropData); // If we dropped something, now is the time to pick it up
Inc(failsafe);
end;
end else
begin
R_Debug('Had trouble grabbing all the ground coffins', 'Leo');
Inc(failsafe);
end;
end else
begin
R_Debug('Had trouble talking to leo @ start', 'Leo');
Inc(failsafe);
end;
if failsafe < 3 then
R_Debug('Re-attempting Leo', 'Leo');
until (failsafe > 2)
if failsafe > 2 then
begin
R_Debug('We have failed leo too many times, aborting Leo solving procedure', 'Leo');
Exit;
end;
end;
end;