Необходимые скилы:
- Tinkering (чтобы мог делать Tinker Tools и лопаты).
- Magery или Chivalry для каста Recal/Sacred Journey.
Необходимые предметы в бекпаке:
- Немного инготов.
- Тинкер тузлы.
- Рунбука к дому/базе, где есть плавильня и ящик куда будут перекладываться инготы.
- Рунбуки к местам добычи.
Особенности: нет проверки на реги (я используют сет на 100% ЛРК), нет проверки на голод (нет особых последствий голодания). Скрипт автоматически делает лопаты, если таковые закончились. Автоматически делает тинкер тузлы, если их меньше двух.
Собственно скрипт:
Code: Select all
program Mining;
const
Forge = $4006F085;
IngotsStorage = $402181C2;
IngotsType = $1BF2;
HomeRuneBook = $4004FFCA;
HomeRuneIndex = 0;
RuneBookShift = 50; //50 for Recal, 75 for Sacred Journey, 100 for Gate Travel
MiningType = $0F39;
TinkerType = $1EB8;
TKNumFirst = 9003;
TKNumSecond = 11;
TKMinerNumFirst = 9003;
TKMinerNumSecond = 18;
IronColor = $0000;
IronCount = $20;
WaitTime = 1000;
RecalTime = 5000;
WaitCycles = 7;
LagWait = 15000;
var
Terminated: Boolean;
CurrentRune: Byte;
CurrentBook: Integer;
OreTypes: array of Word;
GemTypes: array of Word;
RuneBooks: array of Cardinal;
MiningTool: Cardinal;
TinkerTool: Cardinal;
procedure EventMinerGump(Serial, GumpID, X, Y: Cardinal);
begin
if NumGumpButton(0, TKMinerNumSecond) then Exit;
if NumGumpButton(0, TKMinerNumFirst) then Exit;
while IsGump do CloseSimpleGump(0);
end;
procedure EventTinkerGump(Serial, GumpID, X, Y: Cardinal);
begin
if NumGumpButton(0, TKNumSecond) then Exit;
if NumGumpButton(0, TKNumFirst) then Exit;
while IsGump do CloseSimpleGump(0);
end;
function CheckMiningTool: Boolean; //New
begin
CheckLag(LagWait);
FindType(MiningType, Backpack);
if GetType(MiningTool) <> MiningType then MiningTool := FindItem;
Result := FindCount > 0;
end;
function CheckTinkerTool: Boolean; //New
begin
CheckLag(LagWait);
FindType(TinkerType, Backpack);
if GetType(TinkerTool) <> TinkerType then TinkerTool := FindItem;
Result := FindCount > 1;
end;
procedure CreateTKTools;//New
var
Counter: Cardinal;
begin
AddToSystemJournal('Делаем тинкер тузлы');
SetEventProc(evIncomingGump, 'EventTinkerGump');
UseObject(TinkerTool);
Counter := 0;
while True do begin
if (Dead)
or (not Connected)
or (CheckTinkerTool) then begin
SetEventProc(evIncomingGump, '');
Break;
end else Wait(1000);
Inc(Counter);
if Counter > WaitCycles then begin
SetEventProc(evIncomingGump, '');
Break;
end;
end;
while IsGump do CloseSimpleGump(0);
AddToSystemJournal('Сделали тинкер тузлы');
end;
function CreateMiningTools: Boolean;//New
var
Counter: Cardinal;
begin
// AddToSystemJournal('Делаем минер тузлы');
SetEventProc(evIncomingGump, 'EventMinerGump');
if not CheckTinkerTool then begin
CreateTKTools;
end;
UseObject(TinkerTool);
Counter := 0;
while True do begin
if (Dead)
or (not Connected)
or (CheckMiningTool) then Break;
Inc(Counter);
if Counter > WaitCycles then Break;
Wait(1000);
end;
SetEventProc(evIncomingGump, '');
while IsGump do CloseSimpleGump(0);
Result := CheckMiningTool;
// AddToSystemJournal('Сделали минер тузлы');
end;
procedure SmellOre; //New
var
CurOre, CurIndex: Integer;
CurItem: Cardinal;
List: TStringList;
begin
try
List := TStringList.Create;
for CurOre := 0 to Length(OreTypes) - 1 do begin
if Dead or not Connected then Exit;
CheckLag(LagWait);
FindType(OreTypes[CurOre], Backpack);
List.Clear;
if GetFindedList(List) then begin
CurIndex := 0;
while CurIndex < List.Count do begin
if Dead or not Connected then Exit;
CurItem := StrToInt('$' + List.Strings[CurIndex]);
CheckLag(LagWait);
if (GetType(CurItem) <> OreTypes[CurOre])
or (GetQuantity(CurItem) < 2) then begin
Inc(CurIndex);
end else begin
if TargetPresent then CancelTarget;
UseObject(CurItem);
CheckLag(LagWait);
WaitForTarget(WaitTime * 5);
if TargetPresent then begin
TargetToObject(Forge);
CheckLag(LagWait);
Wait(WaitTime);
end;
CheckLag(LagWait);
end;
end;
end;
end;
finally
List.Free;
end;
end;
procedure MoveIngots; //New
var
List: TStringList;
CurIndex: Integer;
CurIngot: Cardinal;
CurIron: Cardinal;
StartCount, ToMove: Integer;
begin
CheckLag(LagWait);
FindType(IngotsType, BackPack);
CurIron := 0;
try
List := TStringList.Create;
if GetFindedList(List) then begin
CurIndex := 0;
while CurIndex < FindCount do begin
if Dead or not Connected then Exit;
CurIngot := StrToInt('$' + List.Strings[CurIndex]);
CheckLag(LagWait);
StartCount := GetQuantity(CurIngot);
if (GetColor(CurIngot) = IronColor)
and (CurIron < IronCount) then begin
ToMove := StartCount - (IronCount - CurIron);
end else begin
ToMove := StartCount;
end;
if ToMove > 0 then begin
if MoveItem(CurIngot, ToMove, IngotsStorage, $FFFF, $FFFF, 0) then begin
Inc(CurIndex);
CurIron := CurIron + (StartCount - ToMove);
CheckLag(LagWait);
Wait(WaitTime);
end;
end else begin
Inc(CurIndex);
CurIron := CurIron + StartCount;
end;
end;
end;
finally
List.Free;
end;
end;
procedure MoveGems; //New
var
List: TStringList;
CurGem, CurIndex: Integer;
CurItem: Cardinal;
begin
CheckLag(LagWait);
try
List := TStringList.Create;
for CurGem := 0 to Length(GemTypes) - 1 do begin
if Dead or not Connected then Exit;
CheckLag(LagWait);
FindType(GemTypes[CurGem], Backpack);
List.Clear;
if GetFindedList(List) then begin
CurIndex := 0;
while CurIndex < List.Count do begin
if Dead or not Connected then Exit;
CurItem := StrToInt('$' + List.Strings[CurIndex]);
CheckLag(LagWait);
if GetType(CurItem) <> GemTypes[CurGem] then begin
Inc(CurIndex);
end else begin
Wait(WaitTime);
MoveItem(CurItem, GetQuantity(CurItem), IngotsStorage, 0, 0, 0);
end;
end;
end;
end;
finally
List.Free;
end;
end;
function RecallRune(RuneBook: Cardinal; Rune: Byte):Boolean; //New
var
Counter: Byte;
X, Y: Word;
begin
Result := False;
X := GetX(Self);
Y := GetY(Self);
CheckLag(LagWait);
Wait(WaitTime);
while Isgump do CloseSimpleGump(0);
if Dead or not Connected then Exit;
UseObject(RuneBook);
CheckLag(LagWait);
Counter := WaitCycles;
while Counter > 0 do begin
if IsGump then Break;
Wait(WaitTime);
CheckLag(LagWait);
Inc(Counter);
end;
if IsGump then begin
if NumGumpButton(0, RuneBookShift + Rune) then begin
CheckLag(LagWait);
Wait(RecalTime);
CheckLag(LagWait);
Result := (X <> GetX(Self)) or (Y <> GetY(Self));
end else Result := False;
end else Result := False;
end;
function GoBase: Boolean; //New
begin
Result := RecallRune(HomeRuneBook, HomeRuneIndex);
end;
function NextRune: Boolean; //New
var
Counter: Cardinal;
begin
Inc(CurrentRune);
if CurrentRune > 15 then begin
CurrentRune := 0
Inc(CurrentBook);
if CurrentBook >= Length(RuneBooks) then CurrentBook := 0;
end;
for Counter := 0 to WaitCycles do begin
if Dead or not Connected then Exit;
Result := RecallRune(RuneBooks[CurrentBook], CurrentRune);
if Result then Break;
Result := RecallRune(RuneBooks[CurrentBook], CurrentRune);
if Result then Break;
GoBase;
Wait(10000);
end;
end;
procedure CheckState;
begin
if MaxWeight < Weight + 60 then begin
while True do begin
if Dead or not Connected then Exit;
if GoBase() then Break;
if GoBase() then Break;
if not RecallRune(RuneBooks[CurrentBook], CurrentRune) then Wait(10000);
end;
SmellOre;
MoveIngots;
MoveGems;
while True do begin
if Dead or not Connected then Exit;
if RecallRune(RuneBooks[CurrentBook], CurrentRune) then Break;
if RecallRune(RuneBooks[CurrentBook], CurrentRune) then Break;
if GoBase() then Continue;
if not NextRune then Wait(10000);
end;
end;
while not CheckMiningTool do begin
if Dead or not Connected then Exit;
CreateMiningTools;
end;
end;
procedure Mine(X, Y: Integer);
var
StaticData: TStaticCell;
Tile: Word;
Z: ShortInt;
Finded: Boolean;
Counter: Byte;
StartTime: TDateTime;
i: Integer;
begin
Finded := False;
StaticData := ReadStaticsXY(X, Y, WorldNum);
for i := 0 to StaticData.StaticCount - 1 do begin
if i >= StaticData.StaticCount then Break;
if (GetTileFlags(2, StaticData.Statics[i].Tile) and $200) = $200 then begin
Tile := StaticData.Statics[i].Tile;
Z := StaticData.Statics[i].Z;
Finded := True;
Break;
end;
end;
CheckState();
while Finded do begin
if Dead or not Connected then Exit;
if TargetPresent then CancelTarget;
while not CheckMiningTool do begin
if Dead or not Connected then Exit;
CreateMiningTools;
end;
CheckLag(LagWait);
Wait(WaitTime);
UseObject(MiningTool);
CheckLag(LagWait);
WaitForTarget(WaitTime);
if TargetPresent then begin
StartTime := Now;
TargetToTile(Tile, X, Y, Z);
Counter := WaitCycles;
Finded := False;
while (not Finded) and (Counter > 0) do begin
CheckLag(LagWait);
if InJournalBetweenTimes('t mine there|is too far away|cannot be seen|is no metal here to mine', StartTime, Now) > 0 then Exit;
if InJournalBetweenTimes('put it in your backpack|loosen some rocks but fail to find any useable ore|have worn out your tool', StartTime, Now) > 0 then Finded := True;
if Not Finded then Wait(200);
Dec(Counter);
end;
CheckState();
end;
end;
end;
procedure MinePoint; //New
var
X, Y: Word;
begin
X := GetX(Self);
Y := GetY(Self);
Mine(X, Y);
Mine(X + 1, Y);
Mine(X + 1, Y + 1);
Mine(X, Y + 1);
Mine(X - 1, Y + 1);
Mine(X - 1, Y);
Mine(X - 1, Y - 1);
Mine(X, Y - 1);
Mine(X + 1, Y - 1);
Mine(X + 2, Y + 2);
Mine(X - 2, Y + 2);
Mine(X - 2, Y - 2);
Mine(X + 2, Y - 2);
end;
begin
RuneBooks := [$40050CAF, $40053D22, $4004E5A6];
OreTypes := [$19B7, $19B8, $19B9, $19BA];
GemTypes := [$3192, $3193, $3194, $3195, $3197, $3198];
CurrentBook := 0;
CurrentRune := 0;
SetEventProc(evIncomingGump, '');
while not Terminated do begin
if Dead then begin
Terminated := True;
Continue;
end;
if not Connected() then begin
Connect();
Wait(10000);
Continue;
end;
NextRune;
MinePoint;
end;
end.
Anvile - идентификатор плавильни.
IngotsStorage - идентификатор ящика для инготов.
IngotsType - тип инготов.
HomeRuneBook - идентификатор рунбуки к дому/базе.
HomeRuneIndex - индекс руны к дому (нумерация начинается с 0).
RuneBookShift - сдвиг кодов кнопок в рунбуке (50 for Recal, 75 for Sacred Journey, 100 for Gate Travel).
MiningType - тип тузлов для майнинга.
TinkerType - тип тинкер тузлов
TKNumFirst - номер кнопки "Tools" в гампе тинкера (для создания тинкер тузлов).
TKNumSecond - номер кнопки для изготовления тинкер тузлов;
TKMinerNumFirst - номер кнопки "Tools" в гампе тинкера (для создания лопат).
TKMinerNumSecond - номер кнопки для изготовления лопат (если используете кирки - не забудьте поменять ещё и MiningType).
IronColor - цвет инготов айрона.
IronCount - количество инготов айрона, которое чар оставляет у себя после переплавки (для изготовления лопат и тинкер тузлов).
WaitTime - стандартное время ожидания.
RecalTime - время ожидания рекола.
WaitCycles - количество циклов ожидания.
LagWait - время ожидания лага.
OreTypes - массив с типами кучек руды (их ведь может быть несколько). Инициализируется в основной процедуре скрипта.
GemTypes - массив с типами добываемых камней (их тоже может быть несколько). Инициализируется в основной процедуре скрипта.
RuneBooks - массив с идентификаторами рунбук к местам добычи (тоже может быть несколько). Инициализируется в основной процедуре скрипта.
P.S.: В зависимости от шарда могут различаться коды кнопок как крафтерских меню, так и гампа рун-буки. Так что к этим вещам Ваше отдельное внимание.