faq/stealth/lumberjacking.txt · Last modified: 2020/12/14 08:05 (external edit)
 

Lumberjacking

An option with cutting the woods near the bank / secure.
Check your settings: UseBank, xTileSunduk and TileSunduk - coordinates in the city from where the bank is called or secure's coordinates, MyMaxWeight - if more then bring to the bank and Sunduk - bank's or secure's ID. In Sunduk put axes, fried fish and ingots, in case the axe is broken, your caracter can make it himself (only if there are tinkertools in the bag).

Program AutoLumber_SW;

{$Include 'all.inc'}

const
/////////////////////////////////////////////////
// Obligatory changes in script's settings.    //
//                                             //
// Coordinates of the chest                    //
// Minoc:                                      //
xTileSunduk = 2516;                            //
yTileSunduk = 553;                             //
//                                             //
/////////////////////////////////////////////////

// Possible changes in script's settings:
MyMaxWeight = 120;// Maximum weight
Hatchet = $0F43;   // Type of axe
UseArms = 0;
Sunduk = $5099A365;

// Size of area
iTTileCount = 39;   // Type of tiles (change it only when area is changed)
iCTileCount = 4;    // Number of spots (meadows' centres), where you want to gather information about the trees (meadow = 30х30 tiles)

// Journal
Msg1 = 'You stop lumberjacking.';
Msg2 = 'That is too far away';
Msg3 = 'hack';
Msg4 = 'You decide not to chop wood';
Msg5 = 'no wood here to chop...';
Msg6 = 'appears immune';
Msg7 = 'Try chopping';
Msg8 = 'reach this';
Msg9 = 'tool breaks';

// Additional
RunSpeed = 250;
iRadiusSearch = 12; // Radius (not the diameter!) search of trees within the tiles around the character
Logs = $1BDD;       // Type of logs
WoodType = $0F90;   // Type of deadwoods

type
ChopTile = Record
x, y : Integer;
end;

var
Regs : array [1..3] of Cardinal;
FoundTilesArray : TFoundTilesArray;
TempFoundTilesArray, ChopTilesArray : array of TFoundTile;
TreeTile:array [0..iTTileCount] of word;
ChopTiles : array[1..iCTileCount] of ChopTile;
ctime : TDateTime;
i : Integer;
n: TDateTime;


procedure CheckDeadLocal;
begin

  UOSay('.rescue');
  Wait(1000);
  newMoveXY(1416,1697,true,0,True); //Идём в Маркет
  Wait(500);
  newMoveXY(5749,1151,true,0,True); //Идём в Минок
  Wait(500);
  UOSay('Minoc');
  Wait(500);

end;

// Initializing an arrea of tree tile types
procedure InitTTilesArray;
begin

  TreeTile[0]:=3274;
  TreeTile[1]:=3275;
  TreeTile[2]:=3277;
  TreeTile[3]:=3280;


  TreeTile[4]:=3283;
  TreeTile[5]:=3286;
  TreeTile[6]:=3288;
  TreeTile[7]:=3290;


  TreeTile[8]:=3293;
  TreeTile[9]:=3296;
  TreeTile[10]:=3299;
  TreeTile[11]:=3302;


  TreeTile[12]:=3320;
  TreeTile[13]:=3323;
  TreeTile[14]:=3326;
  TreeTile[15]:=3329;


  TreeTile[16]:=3393;
  TreeTile[17]:=3394;
  TreeTile[18]:=3395;
  TreeTile[19]:=3396;


  TreeTile[20]:=3415;
  TreeTile[21]:=3416;
  TreeTile[22]:=3417;
  TreeTile[23]:=3418;


  TreeTile[24]:=3419;
  TreeTile[25]:=3438;
  TreeTile[26]:=3439;
  TreeTile[27]:=3440;


  TreeTile[28]:=3441;
  TreeTile[29]:=3442;
  TreeTile[30]:=3460;
  TreeTile[31]:=3461;


  TreeTile[32]:=3462;
  TreeTile[33]:=3476;
  TreeTile[34]:=3478;
  TreeTile[35]:=3480;


  TreeTile[36]:=3482;
  TreeTile[37]:=3484;
  TreeTile[38]:=3492;
  TreeTile[39]:=3496;
end;

// Initializing an array of coordinates to find trees
procedure InitCTilesArrayFirst;
begin
  ChopTiles[1].x := 2491;
  ChopTiles[1].y := 538;

  ChopTiles[2].x := 2502;
  ChopTiles[2].y := 523;

  ChopTiles[3].x := 2488;
  ChopTiles[3].y := 551;

  ChopTiles[4].x := 2507;
  ChopTiles[4].y := 536;
end;

// Initializing system variables
procedure InitSystem;
begin
  SetRunUnmountTimer(RunSpeed);
  SetArrayLength(ChopTilesArray, 1);
end;

// Initializing regs
procedure InitReg;
begin
  Regs[1] := $0F85;      // Ginseng
  Regs[2] := $0F88;      // Nightshade
  Regs[3] := $0F86;      // Mandrake Roots
end;

// Trees search
procedure SearchTree;
var
i, j : Integer;
iFoundTilesArrayCount : word;
iTempFoundTilesArrayCount : Integer;

begin
  for i:= 0 to iTTileCount do
  begin
    iFoundTilesArrayCount := GetStaticTilesArray((GetX(Self) - iRadiusSearch), (GetY(Self) - iRadiusSearch), (GetX(Self) + iRadiusSearch), (GetY(Self) + iRadiusSearch), 1, TreeTile[i], FoundTilesArray);
    if iFoundTilesArrayCount > 0 then
    begin
      SetArrayLength(TempFoundTilesArray, Length(TempFoundTilesArray) + iFoundTilesArrayCount);
      for j := 0 to iFoundTilesArrayCount - 1 do
      begin
        TempFoundTilesArray[iTempFoundTilesArrayCount + j] := FoundTilesArray[j];
      end;
      iTempFoundTilesArrayCount := iTempFoundTilesArrayCount + iFoundTilesArrayCount;
    end;
  end;
  AddToSystemJournal('Trees found: ' + IntToStr(iTempFoundTilesArrayCount));
end;

// Clear duplicated records (Vizit0r :P)
procedure ClearDuplicate;
var
i, j : Integer;

begin
  ChopTilesArray[Length(ChopTilesArray) - 1] := TempFoundTilesArray[0];
  for i:=1 to Length(TempFoundTilesArray) - 1 do
  begin
    for j:=0 to Length(ChopTilesArray) - 1 do
    if (ChopTilesArray[j] = TempFoundTilesArray[i]) then
    break;
    if j > Length(ChopTilesArray) - 1 then
    begin
      SetArrayLength(ChopTilesArray, Length(ChopTilesArray) + 1);
      ChopTilesArray[Length(ChopTilesArray) - 1] := TempFoundTilesArray[i];
    end;
  end;
  AddToSystemJournal('After removing the duplicated, trees left:' + IntToStr(Length(ChopTilesArray)));
end;

// Raising to the power of 2 (Shinma)
function sqr(a:LongInt):LongInt;
begin
  result:=a*a;
end;

// Calculate the length of the vector (Shinma)
function vector_length(c_2:TFoundTile):LongInt;
begin
  result:=Round(sqrt(sqr(GetX(self)-c_2.X)+sqr(GetY(self)-c_2.Y)));
end;

// "Quick sort" by the length of the vector, from the center of the last meadow to all the collected tree coordinates
procedure QuickSort(A: array of TFoundTile; l,r: integer);
var
i, j: Integer;
x, y: TFoundTile;

begin
  i := l;
  j := r;
  x := A[((l + r) div 2)];
  repeat
    while vector_length(A[i]) < vector_length(x) do inc(i);
    while vector_length(x) < vector_length(A[j]) do dec(j);
    if not (i>j) then
    begin
      y:= A[i];
      A[i]:= A[j];
      A[j]:= y;
      inc(i);
      dec(j);
    end;
  until i>j;
  if l < j then QuickSort(ChopTilesArray, l,j);
  if i < r then QuickSort(ChopTilesArray, i,r);
end;

// Find, eliminate duplicates, sort trees
procedure MarkTrees;
begin
  for i:= 1 to iCTileCount do
  begin
    NewMoveXY(ChopTiles[i].x, ChopTiles[i].y, False, 1, False);
    SearchTree;
    AddToSystemJournal('Trres found total: ' + IntToStr(Length(TempFoundTilesArray)));
    ClearDuplicate;
  end;
  QuickSort(ChopTilesArray, 0, Length(ChopTilesArray) - 1);
end;

// Unloading (Edred)
procedure Discharge;
// Unload the chopped wood into the chest
// chopped - Regs in array [1..3]
// logs constanta - Logs
var
m : integer;
tmpid, tmpstack, tmpcolor : Cardinal;
tmpname : String;
begin
  AddToSystemJournal('Unloading');
  waitconnection(3000);
  if Dead then CheckDeadLocal;
  UOSay('banka');
  UseObject(Sunduk);
  wait(1000);
  checksave;
  // Regs
  for m := 1 to 3 do
  begin
    Repeat
      tmpid := Findtype(Regs[m],backpack);
      if tmpid = 0 then break;
      addtosystemjournal( 'Found ' + inttostr(GetQuantity(tmpid)) + ' regs');
      MoveItem(tmpid,GetQuantity(tmpid),Sunduk,0,0,0);
      wait(1000);
      CheckSave;
    until tmpid = 0;
  end;
  // Deed of woods
  Repeat
    tmpid := Findtype(WoodType,backpack);
    if tmpid = 0 then break;
    addtosystemjournal( 'Found ' + inttostr(GetQuantity(tmpid)) + ' dead woods');
    tmpstack := Findtype(WoodType,Sunduk);
    // If not found in the bank, then a container will be used
    if tmpstack = 0 then tmpstack := Sunduk;
    MoveItem(tmpid,GetQuantity(tmpid),tmpstack,0,0,0);
    wait(1000);
    CheckSave;
  until tmpid = 0;
  // Logs
  Repeat
    tmpid := Findtype(Logs,backpack);
    if tmpid = 0 then break;
    tmpcolor := GetColor(tmpid);
    tmpname := ' unknown logs';
    case tmpcolor of
      $0000 : tmpname := ' logs';
      $0505 : tmpname := ' Birch logs ';
      $0654 : tmpname := ' Cherry logs ';
      $048A : tmpname := ' Swamp logs ';
      $0415 : tmpname := ' Oak logs ';
      $0203 : tmpname := ' Hardranger logs ';
      $0487 : tmpname := ' Jade logs ';
      $0654 : tmpname := ' Cherry logs';
      $0542 : tmpname := ' Stormteal logs';
      $0489 : tmpname := ' Blizzard logs';
      $066D : tmpname := ' Vulcanic logs';
      $0492 : tmpname := ' Vampiric logs';
      $0488 : tmpname := ' Zulu logs';
      $0485 : tmpname := ' Darkness logs';
      $0498 : tmpname := ' Elven logs';
    end;
    addtosystemjournal( 'Found ' + inttostr(GetQuantity(tmpid)) + tmpname);
    repeat
      tmpstack := FindtypeEx(Logs,tmpcolor,Sunduk,False);
      if GetQuantity(tmpstack) >= 1500 then Ignore(tmpstack);
    until (tmpstack = 0) OR (GetQuantity(tmpstack) < 1500);
    // If not found in the chest, then a container will be used
    if tmpstack = 0 then tmpstack := Sunduk;
    MoveItem(tmpid,GetQuantity(tmpid),tmpstack,0,0,0);
    wait(1000);
    CheckSave;
  until tmpid = 0;
  IgnoreReset;
  hungry(1,sunduk);
  AddToSystemJournal('Unloading finished');
  AddToSystemJournal('Logs:'+IntToStr(CountEx($1BDD,$0000,Sunduk))+' '+'Birch:'+IntToStr(CountEx($1BDD,$0505,Sunduk))+' '+'Cherry:'+IntToStr(CountEx($1BDD,$0654,Sunduk))+' '+'Swamp:'+IntToStr(CountEx($1BDD,$048A,Sunduk))+' '+'Oak:'+IntToStr(CountEx($1BDD,$0415,Sunduk))+' '+'Hardranger:'+IntToStr(CountEx($1BDD,$0203,Sunduk))+' '+'Jade:'+IntToStr(CountEx($1BDD,$0487,Sunduk))+' '+'Stormteal:'+IntToStr(CountEx($1BDD,$0542,Sunduk))+' '+'Blizzard:'+IntToStr(CountEx($1BDD,$0489,Sunduk))+' '+'Vulcanic:'+IntToStr(CountEx($1BDD,$066D,Sunduk))+' '+'Vampiric:'+IntToStr(CountEx($1BDD,$0492,Sunduk))+' '+' Zulu:'+IntToStr(CountEx($1BDD,$0488,Sunduk))+' Darkness:'+IntToStr(CountEx($1BDD,$0485,Sunduk))+' Elven:'+IntToStr(CountEx($1BDD,$0498,Sunduk)));
end;

// Go to the chest and unload
procedure UnloadOrDead;
begin
  NewMoveXY(xTileSunduk, yTileSunduk, false, 0, true);
  if not Dead then begin Discharge; end
  else begin AddToSystemJournal('The character is dead.'); SetARStatus(False); Disconnect; end;
end;

procedure ArmsLore;
var
d, t: TDateTime;

begin
  d:=StrToTime('0:00:11');
  if ((now - n) > d) or (n = 0) then
  begin
    t:=now;
    WaitTargetType($0F51);
    UseSkill('Arms Lore');
    WaitJournalLineSystem(t, 'This|tell', 3000);
    if TargetPresent then CancelTarget;
    n:=now;
  end;
end;

procedure TinkerHatchet;
begin
  UseObject(sunduk);
  if GetQuantity(FindType($1BF2, backpack)) > 0 then MoveItem(FindItem, GetQuantity(FindItem), Sunduk, 0, 0, 0);
  if GetQuantity(FindType($1BF2, Sunduk)) > 4 then
  begin
    repeat
      MoveItem(FindItem,4,backpack,0,0,0);
      Wait(500);
      if FindType($1EBC,backpack) = 0 then MoveItem(FindType($1EBC,Sunduk),1,backpack,0,0,0);
      WaitMenu('to make', 'Deadly Tools');
      WaitMenu('to make', 'Hatchet');
      UseType($1EBC,$ffff);
      WaitForTarget(5000);
      If TargetPresent then TargetToObject(FindType($1BF2,backpack));
      Wait(7300);
      MoveItem(FindType($1EBC,backpack),1,Sunduk,0,0,0);
    until FindType(Hatchet, backpack) > 0;
  end;
  if GetQuantity(FindType(Hatchet, backpack)) < 1 then 
  begin TinkerHatchet; end
  else begin Equip(RHandLayer, finditem); wait(500); end;
end;

// Chop trees (Edred)
function LumbCurTree(tile,x,y,z : Integer) : Boolean;
// chop on a specipied tile. Return false if too much or the character is dead.
var
q, m1, m2, m3, m4, m5, m6, m7, m8, m9, CountFizzle, NextTree : integer;
t: TDateTime;
oldx, oldy : Integer;

begin
  if Dead then CheckDeadLocal;
  Result := true;
  CountFizzle := 0;
  if (ObjAtLayer(LHandLayer) = 0) and (FindType(Hatchet, backpack) = 0)  then
  begin
    oldx := GetX(Self); oldy := GetY(Self);
    NewMoveXY(xTileSunduk,yTileSunduk,false,0,True);
    UOSay('banka');
    UseObject(sunduk);
    wait(1000);
    if FindType(Hatchet, Sunduk) > 0 then
    begin
      wait(500);
      Equip(RHandLayer, finditem);
      wait(500);
    end
    else
    begin
      TinkerHatchet;
      wait(500);
    end;
    NewMoveXY(oldx,oldy,false,0,True);
  end;
  wait(1000);
  repeat
    if UseArms = 1 then ArmsLore;
    t:=now;
    if WarMode = true then SetWarMode(false);
    if TargetPresent then CancelTarget;
    ctime := Now;
    if Dead then CheckDeadLocal;
    UseType(Hatchet, $FFFF);
    WaitForTarget(5000);
    If TargetPresent then TargetToTile(tile, x, y, z);
    q := 0;
    repeat
      wait(100);
      q := q + 1;
      checksave;
      m1 := InJournalBetweenTimes(Msg1, ctime, Now);
      m2 := InJournalBetweenTimes(Msg2, ctime, Now);
      m3 := InJournalBetweenTimes(Msg3, ctime, Now);
      m4 := InJournalBetweenTimes(Msg4, ctime, Now);
      m5 := InJournalBetweenTimes(Msg5, ctime, Now);
      m6 := InJournalBetweenTimes(Msg6, ctime, Now);
      m7 := InJournalBetweenTimes(Msg7, ctime, Now);
      m8 := InJournalBetweenTimes(Msg8, ctime, Now);
      m9 := InJournalBetweenTimes(Msg9, ctime, Now);
    until (m1<>-1) or (m2<>-1) or (m3<>-1) or (m4<>-1) or (m5<>-1) or (m6<>-1) or (m7<>-1) or (m8<>-1) or (m9<>-1) or Dead or (q > 150);
    if (m2<>-1) or (m3<>-1) or (m4<>-1) then CountFizzle := CountFizzle + 1;
    if Dead or (Weight > MyMaxWeight) then begin Result := false;  end;
    if (q > 150) then NextTree := NextTree + 1;
  until (m5<>-1) OR (m6<>-1) OR (m7<>-1) OR (m8<>-1) OR (m9<>-1) OR (CountFizzle = 10) OR (NextTree > 3);
  if NextTree >= 3 then NextTree := 0;
end;


// Main function
Begin
  InitTTilesArray;
  InitCTilesArrayFirst;
  InitSystem;
  InitReg;
  MarkTrees;
  if Dead then CheckDeadLocal;
  repeat
    for i:= 0 to Length(ChopTilesArray) - 1 do
    begin
      NewMoveXY(ChopTilesArray[i].x, ChopTilesArray[i].y, false, 1, false);
      if not LumbCurTree(ChopTilesArray[i].tile, ChopTilesArray[i].x, ChopTilesArray[i].y, ChopTilesArray[i].z) then UnloadOrDead;
    end;
  until Dead;

End.SetGlobal
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki