Posted: Fri Feb 09, 2007 1:33 Post subject: Скрипты на Mining. Шард Forest Wars.
Пора.
В скрипте на мининг мне было лень выносить маршруты в файл. Кому не нравится, что маршруты забиты прямо в скрипт - переделайте на основе моего скрипта на ламбер (следующий пост).
Скрипт номер 1 (старый- разгрузка в банк)
Code: Select all
program MineBotRohan;
// Скрипт на мининг на шарде FW. Чар копает в шахте около Рохана, бегает на
// разгрузку в банк, при разгрузке сворачивает руду в диды и раскладывает их
// по мешкам в банке (6 мешков). Если чара атакуют - пытается убежать к банку,
// разгрузиться, вылечиться и возвращается копать. Если чар убит - бежит к кресту
// и ресается, восстанавливает здоровье и снова копать. При подходе к шахте
// проверяет наличие кирки, если нет - подходит к респу и берет ее оттуда.
// Один скрипт рассчитан на запуск многим чарам (автонастройка конфигурации).
// Скрипт основан на аналогичных скриптах, написанных мной ранее на инжекте
// и Изиуо.
//
// v.2.01b (c) Edred
//
// 2.01 - ввел дополнительно в ходилку проверку коннекта. Теперь при реконнекте
// чар не сбивается с маршрута. Ввел дополнительные циклы проверок
// успешности разгрузки в банк и реса, если реконнект - процедуры
// будут повторены с новым открыванием банка. Ввел раздельные для
// каждого чара лимиты пещеры (крайние точки, дальше которых копка
// не продолжается).
{$Include 'all.inc'}
const
r1 = 4; r2 = 6; r3 = 14; r4 = 4; r5 = 4; r6 = 4;
rmax = 14; // максимальный
M_nothing1 = 'There is nothing here';
M_nothing2 = 'That is too far';
M_nothing3 = 'Try mining elsewhere.';
M_nothing4 = 'You cannot mine so close';
M_nothing5 = 'You have no line';
M_nothing6 = 'reach';
M_fizzles1 = 'You loosen some rocks';
M_fizzles2 = 'не смогли выкопать ничего';
M_needwait = 'You decide not to mine';
M_success = 'in your pack.';
MaxLimit = 10; // максимальное кол-во физлов одной точки
Pickaxe1 = $0E85; // Типы кирок
Pickaxe2 = $0E86;
AnkhID = $4002BD03; // сериал креста для реса
JevelType = $0F29; // тип Jewel of Spirits
Ore1 = $19B7; // 1 Ore
Ore2 = $19BA; // 2 Ore
Ore3 = $19B8; // 3 Ore
Ore4 = $19B9; // 4 Ore
DeedType = $14EF; // Тип дида
Edred = $00013D85;
BOCTOK = $00050859;
Serf = $0004D756;
Zapad=$0004ACFB;
DeadLife = 40; // Временно - если меньше здоровья - мы мертвы
// Точнее, проверить через реконнект.
type Rail = array[1..rmax] of Integer;
var
Rail_1, Rail_2, Rail_3, Rail_4, Rail_5, Rail_6, StartMinPoint : Rail;
minret, MyMaxWeight,CurBagBank, StartFlag, CaveLimit : integer;
BankBoxID,BagInBank1,BagInBank2,BagInBank3,BagInBank4,BagInBank5,BagInBank6 : Cardinal;
flag1,DisGlobalFlag : Boolean;
function InitConfig : Boolean;
// Настройка переменных под конкретного чара
begin
Result := true;
// Rail_1 - Внутри шахты
Rail_1[1] := 1308;Rail_1[2] := 2831;
Rail_1[3] := 1308;Rail_1[4] := 2848;
// Rail_2 - От шахты до ГЗ
Rail_2[1] := 1308;Rail_2[2] := 2848;
Rail_2[3] := 1313;Rail_2[4] := 2848;
Rail_2[5] := 1333;Rail_2[6] := 2828;
// Rail_3 - По ГЗ до точки рядом с крестом
Rail_3[1] := 1350;Rail_3[2] := 2828;
Rail_3[3] := 1351;Rail_3[4] := 2827;
Rail_3[5] := 1370;Rail_3[6] := 2827;
Rail_3[7] := 1370;Rail_3[8] := 2820;
Rail_3[9] := 1376;Rail_3[10] := 2814;
Rail_3[11] := 1376;Rail_3[12] := 2805;
Rail_3[13] := 1371;Rail_3[14] := 2805;
// Rail_4 - Подход к кресту для реса
// маршрут задействуется только если чар убит.
Rail_4[1] := 1371;Rail_4[2] := 2805;
Rail_4[3] := 1371;Rail_4[4] := 2803;
// Rail_5 - Подход к банку
Rail_5[1] := 1339;Rail_5[2] := 2805;
Rail_5[3] := 1339;Rail_5[4] := 2790;
// Rail_6 - маршрут подхода к респу кирок
Rail_6[1] := 1308;Rail_6[2] := 2848;
Rail_6[3] := 1302;Rail_6[4] := 2849;
if GetName(self) = 'Serf' then
begin
BankBoxID := $4004D755;
BagInBank1 := $4001CE4A;
BagInBank2 := $4004EEF5;
BagInBank3 := $4004EEC8;
BagInBank4 := $4004EEE7;
BagInBank5 := $4004EF7D;
BagInBank6 := $4004EF2C;
MyMaxWeight := 350;
StartMinPoint[1] := 1306;
StartMinPoint[2] := 2836;
StartMinPoint[3] := 1306;
StartMinPoint[4] := 2831;
StartMinPoint[5] := 1306;
StartMinPoint[6] := 2827;
CaveLimit := 1283; // Дальше этой точки при копке заходить не будем
exit;
end;
if GetName(self) = 'BOCTOK' then
// if self = BOCTOK then
begin
BankBoxID := $40050856;
BagInBank1 := $4004BB6D;
BagInBank2 := $4004BB30;
BagInBank3 := $4004BB3A;
BagInBank4 := $4004BB92;
BagInBank5 := $4004BB6F;
BagInBank6 := $40053D05;
MyMaxWeight := 350;
StartMinPoint[1] := 1309;
StartMinPoint[2] := 2834;
StartMinPoint[3] := 1309;
StartMinPoint[4] := 2828;
StartMinPoint[5] := 1307;
StartMinPoint[6] := 2823;
CaveLimit := 1283;
exit;
end;
if GetName(self) = 'Vostok' then
begin
BankBoxID := $400478AD;
BagInBank1 := $40060746;
BagInBank2 := $40060727;
BagInBank3 := $4006071A;
BagInBank4 := $4006072B;
BagInBank5 := $40060722;
BagInBank6 := $4006073F;
MyMaxWeight := 350;
StartMinPoint[1] := 1309;
StartMinPoint[2] := 2834;
StartMinPoint[3] := 1309;
StartMinPoint[4] := 2828;
StartMinPoint[5] := 1307;
StartMinPoint[6] := 2823;
CaveLimit := 1283;
exit;
end;
// if GetName(self) = 'Edred' then
if self = Edred then
begin
BankBoxID := $40013B19;
BagInBank1 := $4004977F;
BagInBank2 := $40046FE7;
BagInBank3 := $40047044;
BagInBank4 := $40046FF8;
BagInBank5 := $40053A0A;
BagInBank6 := $400539FB;
MyMaxWeight := 600;
StartMinPoint[1] := 1306;
StartMinPoint[2] := 2838;
StartMinPoint[3] := 1306;
StartMinPoint[4] := 2829;
StartMinPoint[5] := 1306;
StartMinPoint[6] := 2824;
CaveLimit := 1283;
exit;
end;
// if GetName(self) = 'Zapad' then
if self = Zapad then
begin
BankBoxID := $4004ACE3;
BagInBank1 := $400395E2;
BagInBank2 := $400395B3;
BagInBank3 := $40039494;
BagInBank4 := $40039441;
BagInBank5 := $4003940D;
BagInBank6 := $400395C5;
MyMaxWeight := 350;
StartMinPoint[1] := 1297;
StartMinPoint[2] := 2842;
StartMinPoint[3] := 1294;
StartMinPoint[4] := 2845;
StartMinPoint[5] := 1291;
StartMinPoint[6] := 2848;
CaveLimit := 1276;
exit;
end;
if GetName(self) = 'Driada' then
begin
BankBoxID := $4004D051;
BagInBank1 := $40043356;
BagInBank2 := $40034519;
BagInBank3 := $4003465E;
BagInBank4 := $40034371;
BagInBank5 := $400344AD;
BagInBank6 := $400345FD;
MyMaxWeight := 350;
StartMinPoint[1] := 1297;
StartMinPoint[2] := 2842;
StartMinPoint[3] := 1294;
StartMinPoint[4] := 2845;
StartMinPoint[5] := 1291;
StartMinPoint[6] := 2848;
CaveLimit := 1276;
exit;
end;
// Если дошли до сюда - это плохо!
Result := false;
addtosystemjournal('Error: Не могу настроиться под чара!');
exit;
end;
procedure CheckDead;
begin
if HP < 40 then
begin
Disconnect;
wait(5000);
Connect;
repeat
wait(100);
until Connected;
end;
end;
function CheckPickaxe : Boolean;
// Проверяем есть ли кирка и одеваем ее (если необходимо) в правую руку
// возвращаем true - если все ок, false - если нет кирки
// Проверка на то, что в руке у чара не кирка не производится!
var tmpser : Cardinal;
begin
Result := true;
if (ObjAtLayer(RhandLayer) = 0) then
begin
// ничего в руках нету
tmpser := findtype(Pickaxe1,backpack);
if tmpser = 0 then tmpser := findtype(Pickaxe2,backpack);
if tmpser = 0 then
begin
Result := false;
exit;
end;
if not equip(RhandLayer,tmpser) then
begin
wait(1000);
if not equip(RhandLayer,tmpser) then
begin
Result := false;
exit;
end;
end;
wait(500);
checksave;
end;
end;
procedure CheckHide;
begin
if Hidden then exit;
if WarMode = true then SetWarMode(false);
repeat
UseSkill('Hiding');
wait(4500);
checksave;
until Hidden or (not Connected);
end;
function MiningAround : Integer ;
// копаем вокруг чара
// параметр - максимальный вес.
// возвращаем:
// 1 - вокруг чара все вскопано успешно
// 2 - превышен максимальный вес
// 3 - чар под атакой
// 4 - нет кирки
var k, r, x, y : Integer;
var mn1, mn2, mn3, mn4, mn5, mn6, mf1, mf2, mw1, ms1 : Integer;
var ctime : TDateTime;
begin
Result := 1;
if (HP < MaxHP) or Dead then
begin
Result := 3;
exit;
end;
addtosystemjournal(inttostr(GetX(self)) + ' ' + inttostr(GetY(self)) + ': Начинаем обкопку. Вес чара: ' + inttostr(Weight));
for x := -2 to 2 do
begin
for y := -2 to 2 do
begin
r := 0;
repeat
waitconnection(5000);
if (HP < MaxHP) or Dead then
begin
Result := 3;
exit;
end;
if not CheckPickaxe then
begin
Result := 4;
exit;
end;
CheckHide;
if TargetPresent then CancelTarget;
if WarMode = true then SetWarMode(false);
ctime := Now;
UseObject(ObjAtLayer(RHandLayer));
WaitForTarget(5000);
If TargetPresent then TargetToTile(1342, GetX(self)+x, GetY(self)+y, GetZ(self));
k := 0;
repeat
wait(100);
k := k + 1;
checksave;
mn1 := InJournalBetweenTimes(M_nothing1, ctime, Now);
mn2 := InJournalBetweenTimes(M_nothing2, ctime, Now);
mn3 := InJournalBetweenTimes(M_nothing3, ctime, Now);
mn4 := InJournalBetweenTimes(M_nothing4, ctime, Now);
mn5 := InJournalBetweenTimes(M_nothing5, ctime, Now);
mn6 := InJournalBetweenTimes(M_nothing6, ctime, Now);
mf1 := InJournalBetweenTimes(M_fizzles1, ctime, Now);
mf2 := InJournalBetweenTimes(M_fizzles2, ctime, Now);
ms1 := InJournalBetweenTimes(M_success, ctime, Now);
until (mn1<>-1) or (mn2<>-1) or (mn3<>-1) or (mn4<>-1) or (mn5<>-1) or (mn6<>-1) or (mf1<>-1) or (mf2<>-1) or (ms1<>-1) or (HP < MaxHP) or Dead or (k > 300);
if (HP < MaxHP) or Dead then
begin
Result := 3;
exit;
end;
if Weight > MyMaxWeight then
begin
Result := 2;
exit;
end;
if (mf1<>-1) or (mf2<>-1) then
begin
r := r + 1;
if r >= 10 then break
else continue;
end;
if (mw1<>-1) then wait(3000);
until (mn1<>-1) or (mn2<>-1) or (mn3<>-1) or (mn4<>-1) or (mn5<>-1) or (mn6<>-1);
end;
end;
end;
procedure GotoRail(TmpR : Rail; TmpRD : Integer; dir, guard : Boolean);
// TmpR - маршрут, по которому двигаться
// TmpRD - размер этого массива
// dir - направление перемещения по маршруту (true - прямое, false - обратное)
// guard - звать гвардов если бьют по дороге или нет (true - звать, false - нет)
// v.1.21 (c) Edred, основана на моих аналогичных функциях для Инжекта и Изи.
var i,k,x,y : Integer;
begin
// число элементов в массиве четное. Каждые два - это координаты.
// 1 : 1,2 2 : 3,4 3 : 5,6 n : n*2-1,n*2
// обратное направление:
// 1 : max-1,max 2 : max-3,max-2 n : max-n*2+1,max-n*2+2
k := TmpRD/2;
for i := 1 to k do
begin
if dir then
begin x := TmpR[i*2 - 1]; y := TmpR[i*2]; end
else
begin x := TmpR[TmpRD - i*2 + 1]; y := TmpR[TmpRD - i*2 + 2]; end;
if guard AND (HP < MaxHP) then
begin UOSay( 'GUARDS' ); wait(100); end;
repeat
wait(1000);
addtosystemjournal('Отладка: идем в ' + inttostr(x) + ', ' + inttostr(y) + ' [GotoRail]');
newMoveXY(x,y,false,0,true);
addtosystemjournal('Отладка: пришли в ' + inttostr(x) + ', ' + inttostr(y) + ' [GotoRail]');
until (GetX(self)=x) and (GetY(self)=y);
end;
end;
procedure Medita;
// медитация до полного восстановления маны
var
tmptime : TDateTime;
k : Integer;
begin
if WarMode = true then SetWarMode(false);
waitconnection(5000);
if (Mana <= MaxMana) then
begin
tmptime := Now;
k:=0;
repeat
useskill('meditation');
wait(2000);
k := k + 1;
checksave;
until (InJournalBetweenTimes('reached full mana', tmptime, Now)<>-1) or (k = 100);
addtosystemjournal('медитация закончена');
end;
end;
procedure HealChar;
// лечение чара спирит спиком до полного здоровья
var
tmptime : TDateTime;
k : Integer;
begin
repeat
waitconnection(3000);
tmptime := Now;
k := 0
UseSkill('Spirit Speak');
repeat
wait(100);
k := k + 1;
until (InJournalBetweenTimes('You fail|You channel|You lack|You establish', tmptime, Now)<>-1) or (Mana < (MaxMana - 50)) or (k > 300);
wait(500);
if Mana < 30 then Medita;
until HP = MaxHP;
end;
function DischargeBank : Boolean;
// Разгружаем пак чара в банк. Возвращаем:
// 1 - все ок, пак разгружен.
// 0 - не получилось.
var
tmpcnt,k : Integer;
tmpid, tmpstack, tmpcont : Cardinal;
tmptime,tmpconnect : TDateTime;
tmpflag : Boolean;
tmpstr : String;
begin
Result := true;
if WarMode = true then SetWarMode(false);
CheckDead;
if Dead then exit;
tmpconnect := ConnectedTime;
UOSay('bank');
wait(1000)
checksave;
// Переместим в банк SA
tmpcnt := 0;
repeat
tmpid := Findtype(SA,backpack);
if tmpid = 0 then break;
addtosystemjournal( 'Отладка: найдено ' + inttostr(GetQuantity(tmpid)) + ' SA');
tmpcnt := tmpcnt + 1;
if tmpcnt > 10 then
begin
addtosystemjournal('Ошибка: не могу переместить SA в банк!');
Result := false;
exit;
end;
tmpstack := Findtype(SA,BankBoxID);
// Если не найден в банке - тогда просто в контейнер
if tmpstack = 0 then tmpstack := BankBoxID;
MoveItem(tmpid,GetQuantity(tmpid),tmpstack,0,0,0);
MoveItem(tmpid,GetQuantity(tmpid),BankBoxID,0,0,0);
wait(1000);
CheckSave;
until tmpid = 0;
// Переместим в банк джевелы
tmpcnt := 0;
repeat
tmpid := Findtype(JevelType,backpack);
if tmpid = 0 then break;
addtosystemjournal( 'Отладка: найдено ' + inttostr(GetQuantity(tmpid)) + ' Jewels of Spirit');
tmpcnt := tmpcnt + 1;
if tmpcnt > 10 then
begin
addtosystemjournal('Ошибка: не могу переместить Jewels of Spirit в банк!');
Result := false;
exit;
end;
tmpstack := Findtype(JevelType,BankBoxID);
// Если не найден в банке - тогда просто в контейнер
if tmpstack = 0 then tmpstack := BankBoxID;
MoveItem(tmpid,GetQuantity(tmpid),tmpstack,0,0,0);
MoveItem(tmpid,GetQuantity(tmpid),BankBoxID,0,0,0);
wait(1000);
CheckSave;
until tmpid = 0;
// Свернем руду в паке в диды
addtosystemjournal( 'Отладка: будем сворачивать диды');
repeat
tmpid := Findtype(Ore1,backpack);
if tmpid = 0 then tmpid := Findtype(Ore2,backpack);
if tmpid = 0 then tmpid := Findtype(Ore3,backpack);
if tmpid = 0 then tmpid := Findtype(Ore4,backpack);
if tmpid = 0 then break;
addtosystemjournal( 'Отладка: нашли Ore в количестве ' + inttostr(GetQuantity(tmpid)));
if TargetPresent then CancelTarget;
tmptime := Now;
UOSay('.tradedeed');
WaitForTarget(5000);
If TargetPresent then TargetToObject(tmpid);
k := 0;
repeat
wait(100);
k := k + 1;
until (InJournalBetweenTimes('Вы создали торговый документ', tmptime, Now)<>-1) or (k > 300);
addtosystemjournal( 'Отладка: у нас ' + inttostr(Count(DeedType)) + ' дидов в паке');
until tmpid = 0;
if tmpconnect < ConnectedTime then
begin
// был реконнект чара
Result := false;
exit;
end;
// Реконнекта не было, так что попробуем сложить диды в банк
// проверим какой мешок свободен
tmpflag := false;
tmpstr := 'Перед разгрузкой:';
CurBagBank := 1;
repeat
Case CurBagBank of
1 : tmpcont := BagInBank1;
2 : tmpcont := BagInBank2;
3 : tmpcont := BagInBank3;
4 : tmpcont := BagInBank4;
5 : tmpcont := BagInBank5;
6 : tmpcont := BagInBank6;
end;
UseObject(tmpcont);
wait(1000)
checksave;
tmpcnt := CountEx(DeedType,$FFFF,tmpcont);
addtosystemjournal( 'Отладка: в мешке N' + inttostr(CurBagBank) + ' - ' + inttostr(tmpcnt) + ' дидов');
tmpstr := tmpstr + ' bag' + inttostr(CurBagBank) + ': ' + inttostr(tmpcnt);
if tmpcnt > 240 then
begin
CurBagBank := CurBagBank + 1;
if CurBagBank = 7 then
begin
addtosystemjournal('Error: все мешки полные!');
DisGlobalFlag := false;
Result := false;
exit;
end;
end
else tmpflag := true;
until tmpflag;
AddtoSystemJournal(tmpstr);
// переложим диды в выбранный мешок
repeat
tmpid := Findtype(DeedType,backpack);
if tmpid = 0 then break;
MoveItem(tmpid,1,tmpcont,0,0,0);
wait(1000);
CheckSave;
tmpcnt := tmpcnt + 1;
if tmpcnt > 250 then
begin
addtosystemjournal('Error: не могу переложить диды в банк!');
DisGlobalFlag := false;
Result := false;
exit;
end;
until tmpid = 0;
addtosystemjournal( 'Отладка: у нас ' + inttostr(Count(DeedType)) + ' дидов в паке');
if HP < MaxHP then HealChar;
end;
function ResChar : Boolean;
// Рес чара с креста
begin
Result := true;
WaitConnection(5000);
if WarMode = true then SetWarMode(false);
UseObject(AnkhID);
wait(2000);
checksave;
if Dead then
begin
addtosystemjournal('Error: не могу реснуться!');
Result := false;
exit;
end;
HealChar;
end;
procedure RestoreStamina;
// если стамины мало, восстанавливаем ее чару до полной
begin
if Stam < 20 then
begin
repeat
waitconnection(3000);
wait(1000);
until Stam = MaxStam;
end;
end;
procedure GetPickaxe;
// проверяем, есть ли кирка у чара в паке или на нужном слое.
// если ее нет - подходим к респу и берем в пак.
var tmpser : Cardinal;
begin
if (ObjAtLayer(RhandLayer) = 0) and (count(Pickaxe1)=0) and (count(Pickaxe2)=0) then
begin
FindDistance := 3;
// нет у чара кирки
addtosystemjournal('Нужна кирка');
GotoRail(Rail_6,r6,true,false);
repeat
tmpser := findtype(Pickaxe1,ground);
if tmpser = 0 then tmpser := findtype(Pickaxe2,ground);
if tmpser = 0 then
begin
wait(1000);
continue;
end;
// нашли кирку на земле
CheckDead;
if Dead then break;
Grab(tmpser,1);
wait(1000);
checksave;
until (count(Pickaxe1)<>0) or (count(Pickaxe2)<>0);
addtosystemjournal('Кирка с респа взята');
GotoRail(Rail_6,r6,false,false);
end;
end;
Begin
if not InitConfig then exit;
StartFlag := 1;
if (GetX(self) = 1339) and (GetY(self) = 2790) then
begin
// стартуем от банка
addtosystemjournal('Скрипт начинает работу от банка, идем в шахту');
CheckDead;
if not Dead then
begin
HealChar;
RestoreStamina;
end;
GotoRail(Rail_5,r5,false,true);
GotoRail(Rail_3,r3,false,true);
GotoRail(Rail_2,r2,false,false);
CheckDead;
if not Dead then GetPickaxe;
GotoRail(Rail_1,r1,false,false);
end;
repeat
addtosystemjournal('Я в шахте. Начнем с точки ' + inttostr(StartFlag));
Case StartFlag of
1 : begin
newMoveXY( StartMinPoint[1],StartMinPoint[2],False,0,true);
StartFlag := 2;
end;
2 : begin
newMoveXY( StartMinPoint[3],StartMinPoint[4],False,0,true);
StartFlag := 3;
end;
3 : begin
newMoveXY( StartMinPoint[5],StartMinPoint[6],False,0,true);
StartFlag := 1;
end;
end;
repeat
CheckDead;
if Dead then break;
minret := MiningAround;
if minret = 1 then newMoveXY(GetX(self)-3,GetY(self),False,0,false);
if GetX(self) < (CaveLimit + 3) then break;
until minret <> 1;
addtosystemjournal('Идем в город');
GotoRail(Rail_1,r1,true,false);
GotoRail(Rail_2,r2,true,false);
CheckDead;
if not Dead then RestoreStamina;
GotoRail(Rail_3,r3,true,true);
// Проверим, если чар мертв - пора ресаться
CheckDead;
if Dead then
begin
GotoRail(Rail_4,r4,true,false);
addtosystemjournal('Надо ресаться');
repeat
WaitConnection(5000);
flag1 := ResChar;
wait(1000);
until flag1 = true;
RestoreStamina;
GotoRail(Rail_4,r4,false,true);
addtosystemjournal('Идем в шахту');
end
else
begin
// Чар не мертв, идем на разгрузку
RestoreStamina;
GotoRail(Rail_5,r5,true,true);
// Около банка, будем разгружаться
DisGlobalFlag := true;
repeat
WaitConnection(5000);
flag1 := DischargeBank;
wait(100);
if not DisGlobalFlag then exit;
until flag1 = true;
RestoreStamina;
addtosystemjournal('Идем в шахту');
GotoRail(Rail_5,r5,false,true);
end;
// Идем обратно
GotoRail(Rail_3,r3,false,true);
GotoRail(Rail_2,r2,false,false);
CheckDead;
if not Dead then GetPickaxe;
GotoRail(Rail_1,r1,false,false);
until false;
End.
Code: Select all
program MineBotRiven;
// Скрипт на мининг на шарде FW.
// Все тоже самое, но у ривена, разгрузка в сундук, кирки в мешке там же.
// Все чары в один сундук. Маршрутов всего три: шахта-дом, дом-ГЗ, ГЗ-крест.
//
// v.2.08 (c) Edred
{$Include 'all.inc'}
const
r1 = 20; r2 = 14; r3 = 50;
rmax = 50; // максимальный
M_nothing1 = 'There is nothing here';
M_nothing2 = 'That is too far';
M_nothing3 = 'Try mining elsewhere.';
M_nothing4 = 'You cannot mine so close';
M_nothing5 = 'You have no line';
M_nothing6 = 'reach';
M_fizzles1 = 'You loosen some rocks';
M_fizzles2 = 'не смогли выкопать ничего';
M_needwait = 'You decide not to mine';
M_success = 'in your pack.';
MaxLimit = 10; // максимальное кол-во физлов одной точки
Pickaxe1 = $0E85; // Типы кирок
Pickaxe2 = $0E86;
AnkhID = $40001B8F; // сериал креста для реса
JevelType = $0F29; // тип Jewel of Spirits
Ore1 = $19B7; // 1 Ore
Ore2 = $19BA; // 2 Ore
Ore3 = $19B8; // 3 Ore
Ore4 = $19B9; // 4 Ore
Edred = $00013D85;
BOCTOK = $00050859;
Serf = $0004D756;
Zapad=$0004ACFB;
Sunduk = $40054839;
BagPickaxe1 = $4004A7A5;
BagPickaxe2 = $4004A7A2;
DeadLife = 40; // Временно - если меньше здоровья - мы мертвы
// Точнее, проверить через реконнект.
type Rail = array[1..rmax] of Integer;
var
Rail_1, Rail_2, Rail_3, StartMinPoint : Rail;
minret, MyMaxWeight,StartFlag, CaveLimit : integer;
IronCnt,BlueriteCnt,ShadowCnt,DarkIronCnt,AgapiteCnt : Integer;
BlackrockCnt,SilverCnt,DiamondCnt,ValoriteCnt,MytherilCnt : Integer;
GoldCnt,VeriteCnt,BloodRockCnt,HowManyDischarge : Integer;
ResCnt : Integer;
ScriptStartTime : TDateTime;
flag1 : Boolean;
function InitConfig : Boolean;
// Настройка переменных под конкретного чара
begin
Result := true;
// Rail_1: сундук - шахта
Rail_1[1] := 1348; Rail_1[2] := 3128;
Rail_1[3] := 1312; Rail_1[4] := 3128;
Rail_1[5] := 1300; Rail_1[6] := 3116;
Rail_1[7] := 1296; Rail_1[8] := 3116;
Rail_1[9] := 1295; Rail_1[10] := 3115;
Rail_1[11] := 1267; Rail_1[12] := 3115;
Rail_1[13] := 1256; Rail_1[14] := 3104;
Rail_1[15] := 1251; Rail_1[16] := 3104;
Rail_1[17] := 1241; Rail_1[18] := 3094;
Rail_1[19] := 1232; Rail_1[20] := 3094;
// Rail_2: сундук - ГЗ
Rail_2[1] := 1348; Rail_2[2] := 3128;
Rail_2[3] := 1320; Rail_2[4] := 3128;
Rail_2[5] := 1320; Rail_2[6] := 3136;
Rail_2[7] := 1318; Rail_2[8] := 3138;
Rail_2[9] := 1318; Rail_2[10] := 3144;
Rail_2[11] := 1316; Rail_2[12] := 3146;
Rail_2[13] := 1316; Rail_2[14] := 3179;
// Rail_3: ГЗ - крест
Rail_3[1] := 1321; Rail_3[2] := 3184;
Rail_3[3] := 1321; Rail_3[4] := 3208;
Rail_3[5] := 1318; Rail_3[6] := 3211;
Rail_3[7] := 1318; Rail_3[8] := 3226;
Rail_3[9] := 1311; Rail_3[10] := 3233;
Rail_3[11] := 1311; Rail_3[12] := 3243;
Rail_3[13] := 1296; Rail_3[14] := 3258;
Rail_3[15] := 1282; Rail_3[16] := 3258;
Rail_3[17] := 1254; Rail_3[18] := 3286;
Rail_3[19] := 1230; Rail_3[20] := 3286;
Rail_3[21] := 1230; Rail_3[22] := 3260;
Rail_3[23] := 1237; Rail_3[24] := 3253;
Rail_3[25] := 1230; Rail_3[26] := 3253;
Rail_3[27] := 1230; Rail_3[28] := 3250;
Rail_3[29] := 1227; Rail_3[30] := 3253;
Rail_3[31] := 1197; Rail_3[32] := 3253;
Rail_3[33] := 1197; Rail_3[34] := 3251;
Rail_3[35] := 1196; Rail_3[36] := 3251;
Rail_3[37] := 1196; Rail_3[38] := 3253;
Rail_3[39] := 1199; Rail_3[40] := 3253;
Rail_3[41] := 1205; Rail_3[42] := 3259;
Rail_3[43] := 1210; Rail_3[44] := 3259;
Rail_3[45] := 1214; Rail_3[46] := 3255;
Rail_3[47] := 1214; Rail_3[48] := 3242;
Rail_3[49] := 1208; Rail_3[50] := 3242;
// Счетчики разгруженной руды
IronCnt := 0;
BlueriteCnt := 0;
ShadowCnt := 0;
DarkIronCnt := 0;
AgapiteCnt := 0;
BlackrockCnt := 0;
SilverCnt := 0;
DiamondCnt := 0;
ValoriteCnt := 0;
MytherilCnt := 0;
GoldCnt := 0;
VeriteCnt := 0;
BloodRockCnt := 0;
ResCnt := 0;
//
if GetName(self) = 'Serf' then
begin
MyMaxWeight := 320;
StartMinPoint[1] := 1215;
StartMinPoint[2] := 3111;
StartMinPoint[3] := 1217;
StartMinPoint[4] := 3109;
StartMinPoint[5] := 1219;
StartMinPoint[6] := 3107;
CaveLimit := 1205; // Дальше этой точки при копке заходить не будем
exit;
end;
// if GetName(self) = 'BOCTOK' then
if self = BOCTOK then
begin
MyMaxWeight := 320;
StartMinPoint[1] := 1221;
StartMinPoint[2] := 3105;
StartMinPoint[3] := 1223;
StartMinPoint[4] := 3103;
StartMinPoint[5] := 1225;
StartMinPoint[6] := 3101;
CaveLimit := 1205;
exit;
end;
// if GetName(self) = 'Edred' then
if self = Edred then
begin
MyMaxWeight := 600;
StartMinPoint[1] := 1227;
StartMinPoint[2] := 3099;
StartMinPoint[3] := 1229;
StartMinPoint[4] := 3097;
StartMinPoint[5] := 1229;
StartMinPoint[6] := 3094;
CaveLimit := 1211;
exit;
end;
// if GetName(self) = 'Zapad' then
if self = Zapad then
begin
MyMaxWeight := 350;
StartMinPoint[1] := 1229;
StartMinPoint[2] := 3090;
StartMinPoint[3] := 1229;
StartMinPoint[4] := 3088;
StartMinPoint[5] := 1229;
StartMinPoint[6] := 3086;
CaveLimit := 1211;
exit;
end;
// Если дошли до сюда - это плохо!
Result := false;
addtosystemjournal('Error: Не могу настроиться под чара!');
exit;
end;
procedure PrintStatistic;
// выводит в файл с именем charname.log суммарную статистику с запуска скрипта
begin
with TStringList.Create do
try
Add('Скрипт начал работу: ' + DateTimeToStr(ScriptStartTime));
Add(' Сейчас: ' + DateTimeToStr(Now));
Add(' ');
Add('Количество разгрузок: ' + inttostr(HowManyDischarge));
Add(' ');
Add('Добыто:');
Add(' Iron ' + inttostr(IronCnt));
Add(' Dark Iron ' + inttostr(DarkIronCnt));
Add(' Gold ' + inttostr(GoldCnt));
Add(' Silver ' + inttostr(SilverCnt));
Add(' Verite ' + inttostr(VeriteCnt));
Add(' Valorite ' + inttostr(ValoriteCnt));
Add(' Shadow ' + inttostr(ShadowCnt));
Add(' Agapite ' + inttostr(AgapiteCnt));
Add(' Blood Rock ' + inttostr(BloodRockCnt));
Add(' Mytheril ' + inttostr(MytherilCnt));
Add(' Diamond ' + inttostr(DiamondCnt));
Add(' Black Rock ' + inttostr(BlackrockCnt));
Add(' Bluerite ' + inttostr(BlueriteCnt));
Add(' ');
Add('Количество ресов чара: ' + inttostr(ResCnt));
SaveToFile('__' + GetName(self) + '.log');
finally
free;
end;
end;
procedure CheckDead;
begin
if Dead then exit;
if HP < 40 then
begin
SetARStatus(False);
Disconnect;
wait(5000);
Connect;
SetARStatus(True);
repeat
wait(100);
until Connected;
end;
end;
function CheckPickaxe : Boolean;
// Проверяем есть ли кирка и одеваем ее (если необходимо) в правую руку
// возвращаем true - если все ок, false - если нет кирки
// Проверка на то, что в руке у чара не кирка не производится!
var tmpser : Cardinal;
begin
Result := true;
if (ObjAtLayerEx(RhandLayer,self) = 0) then
begin
// ничего в руках нету
tmpser := findtype(Pickaxe1,backpack);
if tmpser = 0 then tmpser := findtype(Pickaxe2,backpack);
if tmpser = 0 then
begin
Result := false;
exit;
end;
if not equip(RhandLayer,tmpser) then
begin
wait(1000);
if not equip(RhandLayer,tmpser) then
begin
Result := false;
exit;
end;
end;
wait(500);
checksave;
end;
end;
procedure CheckHide;
begin
if Hidden then exit;
if WarMode = true then SetWarMode(false);
repeat
UseSkill('Hiding');
wait(4500);
checksave;
until Hidden or (not Connected);
end;
function MiningAround : Integer ;
// копаем вокруг чара
// параметр - максимальный вес.
// возвращаем:
// 1 - вокруг чара все вскопано успешно
// 2 - превышен максимальный вес
// 3 - чар под атакой
// 4 - нет кирки
var k, r, x, y : Integer;
var mn1, mn2, mn3, mn4, mn5, mn6, mf1, mf2, mw1, ms1 : Integer;
var ctime : TDateTime;
begin
Result := 1;
if (HP < MaxHP) or Dead then
begin
Result := 3;
exit;
end;
addtosystemjournal(inttostr(GetX(self)) + ' ' + inttostr(GetY(self)) + ': Начинаем обкопку. Вес чара: ' + inttostr(Weight));
for x := -2 to 2 do
begin
for y := -2 to 2 do
begin
r := 0;
repeat
waitconnection(5000);
if (HP < MaxHP) or Dead then
begin
Result := 3;
exit;
end;
if not CheckPickaxe then
begin
Result := 4;
exit;
end;
CheckHide;
if TargetPresent then CancelTarget;
if WarMode = true then SetWarMode(false);
ctime := Now;
UseObject(ObjAtLayerEx(RhandLayer,self));
WaitForTarget(5000);
If TargetPresent then TargetToTile(1342, GetX(self)+x, GetY(self)+y, GetZ(self));
k := 0;
repeat
wait(100);
k := k + 1;
checksave;
mn1 := InJournalBetweenTimes(M_nothing1, ctime, Now);
mn2 := InJournalBetweenTimes(M_nothing2, ctime, Now);
mn3 := InJournalBetweenTimes(M_nothing3, ctime, Now);
mn4 := InJournalBetweenTimes(M_nothing4, ctime, Now);
mn5 := InJournalBetweenTimes(M_nothing5, ctime, Now);
mn6 := InJournalBetweenTimes(M_nothing6, ctime, Now);
mf1 := InJournalBetweenTimes(M_fizzles1, ctime, Now);
mf2 := InJournalBetweenTimes(M_fizzles2, ctime, Now);
ms1 := InJournalBetweenTimes(M_success, ctime, Now);
until (mn1<>-1) or (mn2<>-1) or (mn3<>-1) or (mn4<>-1) or (mn5<>-1) or (mn6<>-1) or (mf1<>-1) or (mf2<>-1) or (ms1<>-1) or (HP < MaxHP) or Dead or (k > 300);
if (HP < MaxHP) or Dead then
begin
Result := 3;
exit;
end;
if Weight > MyMaxWeight then
begin
Result := 2;
exit;
end;
if (mf1<>-1) or (mf2<>-1) then
begin
r := r + 1;
if r >= 10 then break
else continue;
end;
if (mw1<>-1) then wait(3000);
until (mn1<>-1) or (mn2<>-1) or (mn3<>-1) or (mn4<>-1) or (mn5<>-1) or (mn6<>-1);
end;
end;
end;
procedure GotoRail(TmpR : Rail; TmpRD : Integer; dir, guard : Boolean);
// TmpR - маршрут, по которому двигаться
// TmpRD - размер этого массива
// dir - направление перемещения по маршруту (true - прямое, false - обратное)
// guard - звать гвардов если бьют по дороге или нет (true - звать, false - нет)
// v.1.21 (c) Edred, основана на моих аналогичных функциях для Инжекта и Изи.
var i,k,x,y : Integer;
begin
// число элементов в массиве четное. Каждые два - это координаты.
// 1 : 1,2 2 : 3,4 3 : 5,6 n : n*2-1,n*2
// обратное направление:
// 1 : max-1,max 2 : max-3,max-2 n : max-n*2+1,max-n*2+2
k := TmpRD/2;
for i := 1 to k do
begin
if dir then
begin x := TmpR[i*2 - 1]; y := TmpR[i*2]; end
else
begin x := TmpR[TmpRD - i*2 + 1]; y := TmpR[TmpRD - i*2 + 2]; end;
if guard AND (HP < MaxHP) then
begin UOSay( 'GUARDS' ); wait(100); end;
repeat
wait(1000);
newMoveXY(x,y,False,0,true);
until (GetX(self)=x) and (GetY(self)=y);
end;
end;
procedure Medita;
// медитация до полного восстановления маны
var
tmptime : TDateTime;
k : Integer;
begin
if WarMode = true then SetWarMode(false);
waitconnection(5000);
if (Mana <= MaxMana) then
begin
tmptime := Now;
k:=0;
repeat
useskill('meditation');
wait(2000);
k := k + 1;
checksave;
until (InJournalBetweenTimes('reached full mana', tmptime, Now)<>-1) or (k = 100);
addtosystemjournal('медитация закончена');
end;
end;
procedure HealChar;
// лечение чара спирит спиком до полного здоровья
var
tmptime : TDateTime;
k : Integer;
begin
while (HP<MaxHP) do
begin
waitconnection(3000);
tmptime := Now;
k := 0
UseSkill('Spirit Speak');
repeat
wait(100);
k := k + 1;
until (InJournalBetweenTimes('You fail|You channel|You lack|You establish', tmptime, Now)<>-1) or (Mana < (MaxMana - 50)) or (k > 300);
wait(500);
if Mana < 30 then Medita;
end;
end;
function ResChar : Boolean;
// Рес чара с креста
begin
Result := true;
WaitConnection(5000);
if WarMode = true then SetWarMode(false);
UseObject(AnkhID);
wait(2000);
checksave;
if Dead then
begin
addtosystemjournal('Error: не могу реснуться!');
Result := false;
exit;
end;
ResCnt := ResCnt + 1;
HealChar;
end;
procedure RestoreStamina;
// если стамины мало, восстанавливаем ее чару до полной
begin
if Stam < 20 then
begin
AddToSystemJournal('Необходимо восстановить стамину. Текущий уровень: ' + inttostr(Stam));
repeat
waitconnection(5000);
wait(1000);
until Stam >= MaxStam - 50;
AddToSystemJournal('Минимальная стамина восстановлена. Текущий уровень: ' + inttostr(Stam));
end;
end;
function GetPickaxe : Boolean;
// проверяем, есть ли кирка у чара в паке или на нужном слое.
// если ее нет - открываем сундук и мешок, берем кирку. Если кирки нет
// в мешке - выход.
var tmpser : Cardinal;
begin
Result := true;
waitconnection(3000);
CheckDead;
if Dead then
begin
Result := false;
exit;
end;
if (ObjAtLayerEx(RhandLayer,self) <> 0) or (count(Pickaxe1)<>0) or (count(Pickaxe2)<>0) then exit;
// нет у чара кирки
repeat
CheckDead;
if Dead then
begin
Result := false;
exit;
end;
waitconnection(3000);
UseObject(Sunduk);
wait(1000);
checksave;
UseObject(BagPickaxe1);
wait(1000);
checksave;
tmpser := findtype(Pickaxe1,BagPickaxe1);
if tmpser = 0 then tmpser := findtype(Pickaxe2,BagPickaxe1);
if tmpser <> 0 then
begin
Grab(tmpser,1);
wait(1000);
checksave;
end;
until (count(Pickaxe1)<>0) or (count(Pickaxe2)<>0);
end;
function GetOreColor(c : cardinal) : string;
// сравниваем цвет указанного итема с табличкой и возвращаем
// название этого цвета с пробелом в начале
begin
Result := ' unknown';
Case GetColor(c) of
$0000 : begin Result := ' Iron'; IronCnt := IronCnt + GetQuantity(c); end;
$00BE : begin Result := ' Bluerite'; BlueriteCnt := BlueriteCnt + GetQuantity(c); end;
$0381 : begin Result := ' Shadow'; ShadowCnt := ShadowCnt + GetQuantity(c); end;
$0386 : begin Result := ' Dark Iron'; DarkIronCnt := DarkIronCnt + GetQuantity(c); end;
$0400 : begin Result := ' Agapite'; AgapiteCnt := AgapiteCnt + GetQuantity(c); end;
$0455 : begin Result := ' Blackrock'; BlackrockCnt := BlackrockCnt + GetQuantity(c); end;
$0482 : begin Result := ' Silver'; SilverCnt := SilverCnt + GetQuantity(c); end;
$048F : begin Result := ' Diamond'; DiamondCnt := DiamondCnt + GetQuantity(c); end;
$0515 : begin Result := ' Valorite'; ValoriteCnt := ValoriteCnt + GetQuantity(c); end;
$052D : begin Result := ' Mytheril'; MytherilCnt := MytherilCnt + GetQuantity(c); end;
$0630 : begin Result := ' Gold'; GoldCnt := GoldCnt + GetQuantity(c); end;
$07D1 : begin Result := ' Verite'; VeriteCnt := VeriteCnt + GetQuantity(c); end;
$0994 : begin Result := ' Blood Rock'; BloodRockCnt := BloodRockCnt + GetQuantity(c); end;
end;
end;
function DischargeSunduk : Boolean;
// Разгружаем пак чара в сундук. Возвращаем:
// 1 - все ок, пак разгружен.
// 0 - не получилось.
var tmpcnt : Integer;
tmpid, tmpstack : Cardinal;
tmpconnect : TDateTime;
begin
Result := true;
waitconnection(3000);
tmpconnect := ConnectedTime;
CheckDead;
if Dead then
begin
Result := false;
exit;
end;
UseObject(Sunduk);
wait(1000);
checksave;
// Переместим SA
tmpcnt := 0;
Repeat
tmpid := Findtype(SA,backpack);
if tmpid = 0 then break;
addtosystemjournal( 'Отладка: найдено ' + inttostr(GetQuantity(tmpid)) + ' SA');
tmpcnt := tmpcnt + 1;
if tmpcnt > 10 then
begin
addtosystemjournal('Ошибка: не могу переместить SA!');
Result := false;
exit;
end;
tmpstack := Findtype(SA,Sunduk);
// Если не найден в банке - тогда просто в контейнер
if tmpstack = 0 then tmpstack := Sunduk;
waitconnection(3000);
MoveItem(tmpid,GetQuantity(tmpid),tmpstack,0,0,0);
wait(1000);
CheckSave;
until tmpid = 0;
// Переместим джевелы
tmpcnt := 0;
repeat
tmpid := Findtype(JevelType,backpack);
if tmpid = 0 then break;
addtosystemjournal( 'Отладка: найдено ' + inttostr(GetQuantity(tmpid)) + ' Jewels of Spirit');
tmpcnt := tmpcnt + 1;
if tmpcnt > 10 then
begin
addtosystemjournal('Ошибка: не могу переместить Jewels of Spirit!');
Result := false;
exit;
end;
tmpstack := Findtype(JevelType,Sunduk);
// Если не найден в банке - тогда просто в контейнер
if tmpstack = 0 then tmpstack := Sunduk;
waitconnection(3000);
MoveItem(tmpid,GetQuantity(tmpid),tmpstack,0,0,0);
wait(1000);
CheckSave;
until tmpid = 0;
// Переместим руду
tmpcnt := 0;
repeat
tmpid := Findtype(Ore1,backpack);
if tmpid = 0 then tmpid := Findtype(Ore2,backpack);
if tmpid = 0 then tmpid := Findtype(Ore3,backpack);
if tmpid = 0 then tmpid := Findtype(Ore4,backpack);
if tmpid = 0 then break;
addtosystemjournal( 'Отладка: найдено ' + inttostr(GetQuantity(tmpid)) + GetOreColor(tmpid) +' ore');
tmpcnt := tmpcnt + 1;
if tmpcnt > 10 then
begin
addtosystemjournal('Ошибка: не могу переместить руду!');
Result := false;
exit;
end;
repeat
tmpstack := FindtypeEx(Ore1,GetColor(tmpid),Sunduk,False);
if tmpstack = 0 then tmpstack := FindtypeEx(Ore2,GetColor(tmpid),Sunduk,False);
if tmpstack = 0 then tmpstack := FindtypeEx(Ore3,GetColor(tmpid),Sunduk,False);
if tmpstack = 0 then tmpstack := FindtypeEx(Ore4,GetColor(tmpid),Sunduk,False);
if GetQuantity(tmpstack) >= 65000 then Ignore(tmpstack);
until (tmpstack = 0) OR (GetQuantity(tmpstack) < 65000);
// Если не найден в сундуке - тогда просто в контейнер
if tmpstack = 0 then tmpstack := Sunduk;
waitconnection