Показать сообщение отдельно
Старый 14.11.2008, 13:39   #489
Новичок
 
Аватар для VismuT
 
Регистрация: 29.09.2008
Сообщений: 14
Сказал Спасибо: 3
Имеет 3 спасибок в 1 сообщении
VismuT пока неопределено
По умолчанию Сполер

Долго мучисля, но все таки научил его спойлить. Выкладываю правленый скрипт бота от Alexus.
Огромное спасибо QaK за оказаную помощь и проявленное терпение=)

delphi Код:
{############################################################################# Бот - локомотив от Alexus edit by VismuT (Научился спойлить) версия : 0.3 (бета) дата: 08.04.08 Описание: Бот для кача в принципе любого война. По функциональности это еще не Волкер, но скрипт уже довольно умный :) Охотиться только на заданных мобов. Возможности: - запоминает центр и радиус кача - запоминает список мобов на которых надо охотиться! - запоминает и затем подбирает дроп, упавший с убитых им мобов - умеет лечиться банками (тип банки легко настраивается), ведется учет количества оставшихся банок - управляется из окна чата в самом клиенте - имеет окно для вывода всех параметров и статистики - если моб по какой-то причине стал недосягаемым (стоит за деревом), то через 1 мин БОТ переключится на другого моба. - если бот умирает, то не палимся и прекращаем рыпаться...(скоро появиться возможность логаута) - работает под С4 и С6 Недостатки:   (со временем будет исправлено) - бот не умеет обходить препядствия - бот может увязаться за атаковавшим его другим игроком Инструкция: 1. Запускаем ПакетХак, запускаем игрового клиента 2. Внимательно НАСТРАИВАЕМ параметры в секции настройки, жмем кнопку "Сохранить" и запускаем скрипт. 3. Добираемся до места кача 4. Выбираем в таргет моба на которого хотим охотится и отправляем в общий чат->  1 5. Валим моба. Если все правильно сделали будет выдано сообщение в чате что моб добавлен. 6. Выбираем следующего моба отправляем в общий чат цифру 2, валим его и т.д. можно выбрать до 10 разных тварей. 7. Становимся в центр кача и отправляем в общий чат-> pos , если все правильно то в чате будет выдано сообщение, что координаты заданы. 8. Бежим к краю радиуса кача и отправляем в общий чат-> dist, в чате вылезет сообщение от системы, что радиус задан. 9. Валим как можно больше мобов в округе, становимся примерно в центр и отправляем в общий чат-> start ,    если все сделано верно, то будет выдано соответствующее сообщение. 10. Если бот поймал моба в таргет и побежал его атаковать, то можно свернуть окно игры    и смотреть на информационное окно скрипта. #############################################################################} const //################### Сеция настройки бота ############################################  NickName = 'HiliH';                 // Твой ник в игре  Interlude = true;                 // C4 - false, C6 - true;  HPMedium = 40;                    // Уровень жизни, при котором начинаем глотать банки  HPBottleID = 1061;                //  ItemID 1060=Lesser Healing Potion;    1061=Healing Potion;   1539=Greater Healing Potion;  Vertical = 300;                   // Вертикальный радиус кача  InvRazmer = 99;                   // Размер инвентаря -1 (т.е. если инвентарь 80, то пишем сюда 79) //############# Секция расширенной настройки для опытных ботоводеров :) ###################################  TimerCombat_Interval = 1000;      // частота срабатывания таймера атаки в милисекундах, чем меньше это число, тем быстрее бот будет думать.  TimerPickUp_Interval = 750;       // частота срабатывания таймера сбора дропа, чем меньше это число, тем быстрее бот будет думать.  TimerForm_Interval = 10000;        // частота срабатывания таймера обновления формы, чем меньше это число, тем быстрее будут обновляться данные в форме.  DrinkDelay = 14;                  // минимальное время задержки повторного питься бутылки (10 - 20 сек)  Attack_Time = 60;                 // Время на убивание моба в секундах.  PickUp_Time = 30;                 // Врямя на поднятие дропа в секундах.  OblastVidimosti = 1000;           // Приращение к радиусу кача, для мобов которые стоят прямо на границе радиуса (изменять от 100 до 1000)  maximumItems = 100;               // Размер базы мобов и дропа //########################################################################################  NpcTypeID_List_Razmer = 10;       // Размер списка мобов (не трогать!)  OX = 1; OY = 2; OZ= 3;            //  Служебные константы var  InitMode, PickUpMode, SpoilMode : boolean; //-------------------------------------- БД  --------------------------------------------------  MobsID   : array [1..maximumItems] of integer;  MobsDist : array [1..maximumItems] of integer;           // Расстояние от центра кача  MobsXYZ  : array [1..maximumItems, 1..3] of integer;     // Координаты  MobsAgression : array [1..maximumItems] of boolean;      // Моб атакует меня или стоит в сторонке...  MobsLastIndex: integer;                                  // индекс последнего элемента базы  NpcTypeID_List : array [1..NpcTypeID_List_Razmer] of integer// Список мобов  (коды мобов)  NpcTypeID_List_Count : integer;                          // Текущий размер списка  NpcTypeID_CurrentMob : integer;  Items_ObjectID : array [1..maximumItems] of integer;     // БД дропа с мобов  Items_ItemID : array [1..maximumItems] of integer;  Items_XYZ : array [1..maximumItems, 1..3] of integer;  ItemsLastIndex: integer;  Inventory: array[0..InvRazmer, 0..9] of integer;                // инвентарь (itemType1, ObjectID, ItemID, count, itemType2, CustType1, isEquipped, BodyPart, EnchantLevel, CustType2)  HPBottleObjID, HPBottleCount : integer;                  // ObjID и количество HP-бутылей  TargetID, LastKilledMobObjID : integer;                  // Текущая цель, последний убитый моб  MobsKilled : integer;                                    //   счетчик убитых мобов  Povtor: integer;  CenterX, CenterY, CenterZ : integer;                     // Центр кача  Radius: integer;                                         // Радиус кача //--------------------------------------------------------  MyX, MyY, MyZ : integer;                                 // Мои статы  MyID, MyHP, MyMaxHP: integer;  MyMP, MyMaxMP, MyCP, MyMaxCP: integer;  HPlevelProcent : integer;                                 // уровень жизни в прочентах //--------------------------------------------------------  frm: TForm;                                              // переменные описания формы  log, MobsDBscreen, ItemsDBScreen: TMemo;  panel: TPanel;  frmParamIndex: byte;  textX, textY, textZ, textMyID, textMyHP, textMyMaxHP: TEdit;  textMyMP, textMyMaxMP, textMyCP, textMyMaxCP: TEdit;  textCenterX, textCenterY, textCenterZ, textRadius : TEdit;  textTargetID, textMobX, textMobY, textMobZ : TEdit;  textAttackCycle, textMobsKilled: TEdit; //----------------------------------------------------------  TimerForm, TimerCombat, TimerPickUp : TTimer;              // таймеры  time1: integer;  Calculated_AttackTime, Calculated_PickUpTime : integer;  AttackCycle: integer;                                      // Цикл атаки //############################################################################################## procedure Init; //Вызывается при включении скрипта  begin   ClearDB;   MyID:= 0;        // обнуляем ВСЕ данные   MyX:= 0;   MyY:= 0;   MyZ:= 0;   MyID:= 0;   MyHP:= 0;   MyMaxHP:= 0;   MyMP:= 0;   MyMaxMP:= 0;   MyCP:= 0;   MyMaxCP:= 0;   time1:=1;   SpoilMode:= true;   Calculated_AttackTime:= round (1000 / TimerCombat_Interval * Attack_Time);   Calculated_PickUpTime:= round (1000 / TimerPickUp_Interval * PickUp_Time);   HPlevelProcent:= 0;   HPBottleObjID:= 0;   HPBottleCount:= 0;   InitMode:= true;   TimerCombat:=TTimer.Create(nil);           // создаем таймеры   TimerCombat.OnTimer:=@OnTimerCombat;   TimerCombat.enabled:=false;   TimerCombat.interval:= TimerCombat_Interval;   TimerForm:=TTimer.Create(nil);   TimerForm.OnTimer:=@OnTimerForm;   TimerForm.enabled:=true;   TimerForm.interval:= TimerForm_Interval;   TimerPickUp:=TTimer.Create(nil);   TimerPickUp.OnTimer:=@OnTimerPickUp;   TimerPickUp.enabled:=false;   TimerPickUp.interval:= TimerPickUp_Interval;   frmParamIndex:=0;                          // создаем контролы в форме   frm:= TForm.Create(nil);   frm.Caption:= 'BOT by Alexus ver: 0.3 beta';   frm.BorderStyle := bsSizeable;   frm.Position := poScreenCenter;   frm.Width:=650;   frm.Height:=700;   MobsDBscreen:=TMemo.Create(frm);   MobsDBscreen.parent:=frm;   MobsDBscreen.ReadOnly:=true;   MobsDBscreen.ScrollBars:=2;   MobsDBscreen.Top:=1;   MobsDBscreen.Width:=460;   MobsDBscreen.Height:=285;   MobsDBscreen.Lines.Add('Мобы');   ItemsDBscreen:=TMemo.Create(frm);   ItemsDBscreen.parent:=frm;   ItemsDBscreen.ReadOnly:=true;   ItemsDBscreen.ScrollBars:=2;   ItemsDBscreen.Top:=286;   ItemsDBscreen.Width:=460;   ItemsDBscreen.Height:=285;   ItemsDBscreen.Lines.Add('Дроп');   panel:=TPanel.Create(frm);   panel.parent:=frm;   panel.align:=alRight;   log:=TMemo.Create(panel);   log.parent:=frm;   log.align:=alBottom;   log.ReadOnly:=true;   log.ScrollBars:=2;   log.Width:=570;   log.Height:=100;   log.Lines.Add('...');   textMyID:= CreateTextBox('textMyID');   CreateLabel('Мой ID :');   textX:= CreateTextBox('textX');   CreateLabel('Мой X :');   textY:= CreateTextBox('textY');   CreateLabel('Мой Y :');   textZ:= CreateTextBox('textZ');   CreateLabel('Мой Z :');   textMyHP:= CreateTextBox('textMyHP');   CreateLabel('Мой HP :');   textMyMaxHP:= CreateTextBox('textMyMaxHP');   CreateLabel('Мой MaxHP :');   textMyMP:= CreateTextBox('textMyMP');   CreateLabel('Мой MP :');   textMyMaxMP:= CreateTextBox('textMyMaxMP');   CreateLabel('Мой MaxMP :');   textMyCP:= CreateTextBox('textMyCP');   CreateLabel('Мой CP :');   textMyMaxCP:= CreateTextBox('textMyMaxCP');   CreateLabel('Мой MaxCP :');   inc(frmParamIndex);   textCenterX:= CreateTextBox('textCenterX');   CreateLabel('Ц. кач Х:');   textCenterY:= CreateTextBox('textCenterY');   CreateLabel('Ц. кач Y:');   textCenterZ:= CreateTextBox('textCenterZ');   CreateLabel('Ц. кач Z:');   textRadius:= CreateTextBox('Radius');   CreateLabel('Radius :');   inc(frmParamIndex);   textTargetID:= CreateTextBox('TargetID');   CreateLabel('Цель ID :');   textAttackCycle:= CreateTextBox('AttackCycle');   CreateLabel('Цикл атаки:');   textMobsKilled:= CreateTextBox('MobsKilled');   CreateLabel('Убито моб:');   frm.Show;                // выводим форму на экран   buf:= #$0F;              // принудительно вызываем пакеты инвентаря и userinfo   SendToServerEx(NickName); end; procedure ClearDB;                                          // Очистка БД  var                                                        // Надо все занулять, иначе там хрень всякая вылезает или старые данные   i, n: word;  begin   MobsLastIndex:= 0;                                              // Очищаем переменные   ItemsLastIndex:= 0;   TargetID:= 0;   LastKilledMobObjID:= 0;   MobsKilled:= 0;   Povtor:= 0;   CenterX:= 0;   CenterY:= 0;   CenterZ:= 0;   Radius:= 0;   AttackCycle:= 0;   for i:=1 to NpcTypeID_List_Razmer do NpcTypeID_List[i]:= 0;   NpcTypeID_List_Count:= 0;   NpcTypeID_CurrentMob:= 0;   for i:=1 to maximumItems do                                // Очищаем базу    begin     MobsID[i]:= 0;     MobsDist[i]:= 0;     MobsXYZ[i, OX]:= 0;     MobsXYZ[i, OY]:= 0;     MobsXYZ[i, OZ]:= 0;     MobsAgression[i]:= false;     Items_ObjectID[i]:= 0;     Items_ItemID[i]:= 0;     Items_XYZ[i, OX]:= 0;     Items_XYZ[i, OY]:= 0;     Items_XYZ[i, OZ]:= 0;    end;   for i:=0 to InvRazmer do for n:=0 to 9 do Inventory[i, n]:= 0;  end; function Wait(var tick: integer;Timewait: Integer): Boolean; // сквозная проверка без остановки скрипта (c)dmitry501, modifed by Sh00rGo var   t: integer; begin   result:=false;   t:=Round(Time*86400);   if t>(tick+Timewait) then begin     if tick>0 then result:=true;     tick:=t;   end; end; //############################## Модуль работы с Инвентарем ########################### procedure InventoryCreate; var   i,k, offset : integer; begin   if interlude then offset:= 8 else offset:=0;   for i:=0 to InvRazmer do     if (i<ReadH(4)) then begin       Inventory[i,0]:=ReadH(i*(28+offset)+6)// itemType1       Inventory[i,1]:=ReadD(i*(28+offset)+8)// ObjectId       Inventory[i,2]:=ReadD(i*(28+offset)+12); // ItemID       Inventory[i,3]:=ReadD(i*(28+offset)+16); // count       Inventory[i,4]:=ReadH(i*(28+offset)+20); // itemType2       Inventory[i,5]:=ReadH(i*(28+offset)+22); // CustType1       Inventory[i,6]:=ReadH(i*(28+offset)+24); // isEquipped       Inventory[i,7]:=ReadD(i*(28+offset)+26); // BodyPart       Inventory[i,8]:=ReadH(i*(28+offset)+30); // EnchantLevel       Inventory[i,9]:=ReadH(i*(28+offset)+32); // CustType2     end else       for k:=0 to 9 do Inventory[i,k]:=0; // забиваем нулями end; procedure InventoryUpdate;  var   i,j,k, offset: integer;  begin   if interlude then offset:= 8 else offset:=0;   for j:=0 to (ReadH(2)-1) do    begin     case pck[j*(30+offset)+4] of      #$01: k:=0; // add item, запишет на пустую ячейку      #$02: k:=ReadD(j*(30+offset)+8); // mod item      #$03: begin // remove item, обнулит ячейки удаленного предмета             k:=ReadD(j*(30+offset)+8);             for i:=0 to InvRazmer do if (Inventory[i,0]=k) then              begin               for k:=0 to 9 do Inventory[i,k]:=0;               exit;              end;            end;     end;     for i:=0 to InvRazmer do if (Inventory[i,1]=k) then      begin       Inventory[i,0]:=ReadH(j*(30+offset)+6)// itemType1       Inventory[i,1]:=ReadD(j*(30+offset)+8)// ObjectId       Inventory[i,2]:=ReadD(j*(30+offset)+12); // ItemID       Inventory[i,3]:=ReadD(j*(30+offset)+16); // count       Inventory[i,4]:=ReadH(j*(30+offset)+20); // itemType2       Inventory[i,5]:=ReadH(j*(30+offset)+22); // CustType1       Inventory[i,6]:=ReadH(j*(30+offset)+24); // isEquipped       Inventory[i,7]:=ReadD(j*(30+offset)+26); // BodyPart       Inventory[i,8]:=ReadH(j*(30+offset)+30); // EnchantLevel       Inventory[i,9]:=ReadH(j*(30+offset)+32); // CustType2       break;      end;    end;  end; function GetInv(obj,up,down:integer): integer; // up и down не проверяются    var // 0-itemType1, 1-ObjectId, 2-ItemID, 3-count, 4-itemType2, 5-CustType1, 6-isEquipped, 7-BodyPart, 8-EnchantLevel, 9-CustType2     i: integer;  begin   for i:=0 to InvRazmer do if (Inventory[i,up]=obj) then    begin     Result:=Inventory[i,down];     exit;    end;   Result:=-1; end; {procedure UseItemID(ItemID:integer);       //Использовать предмет с заданным ItemID  var   ObjItemID : integer;  begin   ObjItemID:= GetInv(ItemID,2,1);   if ObjItemID = -1 then exit;   buf:=#$14;   WriteD(ObjItemID);   WriteD(0);   SendToServerEx(NickName);;  end;} procedure UseItemObjID(ItemObjID:integer);       //Использовать предмет с заданным ItemID  begin   buf:=#$14;   WriteD(ItemObjID);   WriteD(0);   SendToServerEx(NickName);;  end; //############################################################################################ function rastoyanie(NpcX, NpcY, NpcZ : integer) : integer; // вычисление растояния между 2 точками  var   dx,dy,dz, summa : integer;  begin   dx:= NpcX-CenterX;   dy:= NpcY-CenterY;   dz:= NpcZ-CenterZ;   summa:= dx*dx+dy*dy;                                            // мне кажется, что так будет быстрее считаться   if summa = 0 then result:= 0 else result:= Round(sqrt(summa))// обход возможной ошибки, если моб стоит прямо в центре кача   if abs(dz) > vertical then result := result + 5000;             // добавляем коррекцию по вертикали end; procedure AddDroppedItem (ObjID, ItemID, X, Y, Z: integer);       // Процедура добавляет дропнутую вещь в БД  begin   inc (ItemsLastIndex);   if ItemsLastIndex > maximumItems then exit;   Items_ObjectID[ItemsLastIndex]:= ObjID;   Items_ItemID[ItemsLastIndex]:= ItemID;   Items_XYZ[ItemsLastIndex, OX]:= X;   Items_XYZ[ItemsLastIndex, OY]:= Y;   Items_XYZ[ItemsLastIndex, OZ]:= Z;   log.Lines.Add('Вещь добавлена, индекс в БД: '+ inttostr(ItemsLastIndex));  end; procedure AddtoDB (id, x,y,z : integer; agression : boolean);     // Процедура добавляет в БД нового моба  var   i:integer;   dist: integer;  begin   dist:= rastoyanie (x,y,z);                                       // вычиляем расстояние от центра кача до моба   if dist > (Radius + OblastVidimosti) then exit;                  // если моб слишко далеко то ничего не делаем   inc (MobsLastIndex);                                             // увеличиваем размер БД   log.Lines.Add('Моб добавлен, индекс в БД: '+ inttostr(i));   if agression then log.Lines.Add('На нас напала какая-то вражина.');   MobsID[MobsLastIndex]:= id;                                                  // Записываем моба   MobsDist[MobsLastIndex]:= dist;   MobsXYZ[MobsLastIndex, OX]:= x;   MobsXYZ[MobsLastIndex, OY]:= y;   MobsXYZ[MobsLastIndex, OZ]:= z;   MobsAgression[MobsLastIndex]:= agression;  end; procedure UpdateDB (i:integer; id, x,y,z : integer; agression : boolean);   // Процедура обновляет данные в БД по мобу  var   dist: integer;  begin   if (MOBSXYZ[i, OX] = x) and (MOBSXYZ[i, OY] = y) and (MobsAgression[i] = agression) then exit// проверяем, а надо ли чего нить менят   dist:= rastoyanie (x,y,z);   if dist > (Radius + OblastVidimosti) then DelDBItem(i) else          // перепроверяем расстояние до моба, если он вышел за границу кача, то удаляем его    begin     log.Lines.Add('Моб обновлен, индекс в БД: '+ inttostr(i));     if agression then log.Lines.Add('На нас напала какая-то вражина.');     MobsDist[i]:= dist;                                    // записываем данные     MobsXYZ[i, OX]:= x;     MobsXYZ[i, OY]:= y;     MobsXYZ[i, OZ]:= z;     MobsAgression[i]:= agression;    end;  end; procedure DelDBItem (i: integer);                              // процедура удалаяет моба из БД  var   n: integer;  begin   log.Lines.Add('Моб удален, индекс в БД: '+ inttostr(i));   MobsID[i]:= 0;   MobsDist[i]:= 0;   MobsXYZ[i, OX]:= 0;   MobsXYZ[i, OY]:= 0;   MobsXYZ[i, OZ]:= 0;   MobsAgression[i]:= false;   if i < MobsLastIndex then for n:= i+1 to MobsLastIndex do       // если надо, производим циклический сдвиг данных в массивах    begin     MobsID[n-1]:= MobsID[n];     MobsDist[n-1]:= MobsDist[n];     MobsXYZ[n-1, OX]:= MobsXYZ[n, OX];     MobsXYZ[n-1, OY]:= MobsXYZ[n, OY];     MobsXYZ[n-1, OZ]:= MobsXYZ[n, OZ];     MobsAgression[n-1]:= MobsAgression[n];    end;   dec (MobsLastIndex);                                        // уменьшаем размер БД  end; procedure DelDroppedItem (i: integer);                         // процедура удалаяет вещь из БД  var   n: integer;  begin   Items_ObjectID[i]:= 0;   Items_ItemID[i]:= 0;   Items_XYZ[i, OX]:= 0;   Items_XYZ[i, OY]:= 0;   Items_XYZ[i, OZ]:= 0;   log.Lines.Add('Вещь удалена, индекс в БД: '+ inttostr(i));   if i < ItemsLastIndex then for n:= i+1 to ItemsLastIndex do    begin     Items_ObjectID[n-1]:= Items_ObjectID[n];     Items_ItemID[n-1] :=  Items_ItemID[n];     Items_XYZ[n-1, OX]:=  Items_XYZ[n, OX];     Items_XYZ[n-1, OY]:=  Items_XYZ[n, OY];     Items_XYZ[n-1, OZ]:=  Items_XYZ[n, OZ];    end;   dec (ItemsLastIndex);  end; function CheckItems (id: integer) : integer;                   // функция проверяет наличие заданной вещи в БД  var   i: integer;  begin   result:= 0;   for i:=1 to ItemsLastIndex do if Items_ObjectID[i] = id then    begin     result:=i;                                                  // И возвращаем его индекс по БД     break;    end;  end; function TestPovtor (id: integer) : integer;                   // функция проверяет наличие заданного моба в БД  var   i: integer;  begin   result:=0;   for i:=1 to MobsLastIndex do if MobsID[i] = id then               // Ищем нужный ID в нашей БД    begin     result:=i;                                                  // И возвращаем его индекс по БД     break;    end;  end; function InMobsList (NpcTypeID: integer) : boolean;            // функция проверяет наличие заданного моба в списке на атаку  var   i: integer;  begin   result:= false;   for i:=1 to NpcTypeID_List_Count do if NpcTypeID_List[i] = NpcTypeID then result:= true;     // проверяем по списку  end; procedure SendMsg(msg:string);                                  // отправка системных сообщений клиенту begin   buf:=#$4A;   WriteD(0);   WriteD(10);   WriteS('');   WriteS(msg);   SendToClientEx(NickName); end; function ValidateData : boolean;                                // функция проверки правильности задания всех параметров для начала кача  begin   if (MyX <> 0) and (MyY <> 0) and (MyZ <> 0) and (MyID <> 0) and (MyHP > 0) and (MyMaxHP > 0) and         // верификация всех данных, чтобы потом в боевом режиме      (MyMP > 0) and (MyMaxMP > 0) and {(MyCP <> 0) and (MyMaxCP <> 0) and }                                 // не перепроверять все данные по 100 раз      (CenterX <> 0) and (CenterY <> 0) and (CenterZ <> 0) and (Radius > 0) and (NpcTypeID_List_Count > 0) then       begin        SendMsg('Все начальные параметры заданы и проверены!');        log.Lines.Add('Все начальные параметры заданы и проверены!');        result:= true;       end      else       begin        SendMsg('Ошибка задания начальных параметров!');        log.Lines.Add('Ошибка задания начальных параметров!');        result:= false;       end;  end; procedure UserCommandsInitMode;    // комманды пользователя для режима настройки бота  begin                              // если комманда обработана удачно, то в чат сообщение не попадет, а будет выдано системное сообщение прямо в клиент   case (ReadS(2)) of    'pos' :   if MyX <> 0 then                        // центр кача               begin                CenterX:= MyX;                CenterY:= MyY;                CenterZ:= MyZ;                SendMsg('Центр кача задан успешно!');                log.Lines.Add('Центр кача задан успешно!');                pck:='';               end;    'dist'if (CenterX <> 0) and (MyX <> 0) then                // радиус кача               begin                Radius:= rastoyanie (MyX,MyY,MyZ);                SendMsg('Радиус кача задан успешно');                SendMsg('R= '+ inttostr(Radius));                log.Lines.Add('Радиус кача задан успешно, R = '+ inttostr(Radius));                pck:='';               end;    'reset'begin                                                // сброс параметров               ClearDB;               SendMsg('БД очищена, введите заново все параметры');               log.Lines.Add('БД очищена!');               pck:='';              end;    '1', '2', '3', '4', '5', '6', '7', '8', '9', '10' :            // задаем мобов               begin                if (NpcTypeID_List_Count+1) <> strtoint(ReadS(2)) then                 begin                  SendMsg('Добавлять мобов можно тока по очереди 1, 2, 3...');                  pck:='';                  exit;                 end;                NpcTypeID_CurrentMob:= strtoint(ReadS(2));                SendMsg('Добавляем моба № '+ ReadS(2));                pck:='';               end;    'start':   begin                                               // собственно запуск бота                if ValidateData and InitMode then                 begin                  SendMsg('ЗАПУСКАЕМ ИСУСТВЕННЫЙ ИНТЕЛЛЕКТ!');                  log.Lines.Add('ЗАПУСКАЕМ ИСУСТВЕННЫЙ ИНТЕЛЛЕКТ!');                  TargetID:=0;                  InitMode:= false;                  TimerCombat.enabled:=true;                      // запускаем таймер                 end                 else                  begin                   SendMsg('Еще не все параметры заданы. Проверьте параметры...');                   log.Lines.Add('Еще не все параметры заданы. Проверьте параметры...');                  end;                pck:='';               end;   end;  end; procedure UserCommandsCombatMode;     // комманды пользователя для боевого режима  begin                                // команды говорят сами за себя)   case (ReadS(2)) of    'pause' : begin               TimerCombat.enabled:= not(TimerCombat.enabled);               pck:='';               if TimerCombat.enabled then                begin                 SendMsg('Искуственный интелект запущен!');                 log.Lines.Add('Искуственный интелект запущен!');                end                else                 begin                  SendMsg('Искуственный интелект приостановлен.');                  log.Lines.Add('Искуственный интелект приостановлен.');                 end              end;    'stop'  : begin               pck:='';               SendMsg('Искуственный интелект остановлен.');               log.Lines.Add('Искуственный интелект остановлен.');               StopGame;              end;   end;  end; procedure StopGame;                     // остановка кача  begin   TimerCombat.enabled:= false; //  InitMode:= true;   TimerPickUp.enabled:=false;   TargetID:= 0;   ClearDB;  end; function GetMinDistID : integer;     // функция поиска ближайшего моба в БД  var   i, dist : integer;  begin   dist:=10000;                       // задаем заранее нереальную дистанцию   for i:=1 to MobsLastIndex do if (MobsID[i] <> 0) and (MobsDist[i] < dist) then    begin                            // фишка в том, что в базе хранятся расстояния не до меня, а до центра кача     dist:= MobsDist[i];             // но в катах то расстояния небольшие     result:= i;                      // если нашли хоть одного моба или несколько возращаем его индекс ближайшего к центру кача    end;   if dist = 10000 then result:= 0;   // иначе возвращаем 0 (ничего не найдено)  end; function AgroTest : integer;        // функция проверяет, атакует ли меня кто-нибудь или нет  var   i: integer;  begin   result:=0;   for i:=1 to MobsLastIndex do if MobsAgression[i] then  // ищем первого попавшегося моба, который нас атакует    begin     result:= i;                                      // возвращаем его индекс по БД     break;    end;  end; procedure PhisicalAttack;          // команда атаки  begin  buf:=#$04; //action   WriteD(TargetID);   WriteD(MyX);   WriteD(MyY);   WriteD(MyZ);   WriteC(0);   SendToServerEx(NickName);   if SpoilMode=true then begin   buf:=hstr('2F FE 00 00 00 00 00 00 00 00');   SendToServerEX(NickName); end;  end; procedure InitPickUpMode(mode: boolean); begin  if mode then   begin    PickUpMode:= true;    TimerCombat.enabled:= false;    TimerPickUp.enabled:= true;   end  else   begin    PickUpMode:= false;    TimerCombat.enabled:= true;    TimerPickUp.enabled:= false;   end; end; procedure OnTimerPickUp (Sender: TObject);         // таймер поднятия дропа  var   povtor: integer;  begin   if (AgroTest > 0) and (TargetID = 0) then    begin     InitPickUpMode(false);     exit;    end;   if (ItemsLastIndex > 0) and (TargetID = 0) then    begin     TargetID:= Items_ObjectID[ItemsLastIndex];     AttackCycle:= 0;     PhisicalAttack;     exit;    end;   if (ItemsLastIndex > 0) and (TargetID > 0) then    begin     inc (AttackCycle);     if ((AttackCycle mod 5) = 0) then PhisicalAttack;     if AttackCycle > Calculated_PickUpTime then      begin       Povtor:= CheckItems(TargetID);       if Povtor <> 0 then DelDroppedItem(Povtor);       TargetID:= 0;      end;     exit;    end;   if (ItemsLastIndex = 0) then InitPickUpMode(false);  end; procedure OnTimerCombat (Sender: TObject);         // боевой таймер, вся логика поведения бота находится именно здесь!!!  var   Agro, MinDistID: integer;  begin   if MobsLastIndex = 0 then    // если нет мобов в базе, то    begin     if ItemsLastIndex > 0 then InitPickUpMode(true);   // надо дроп подбирать     exit;                     // выходим от сюда    end;   if TargetID > 0 then           // если в прицеле есть моб, то    begin                                  // валим вражину     if ((AttackCycle mod 5) = 0) then PhisicalAttack;     inc(AttackCycle);     if AttackCycle > Calculated_AttackTime then              // если валим моба больше минуты, значит это баг...      begin       Povtor:= TestPovtor(TargetID);       if Povtor <> 0 then DelDBItem(Povtor);       TargetID:= 0;      end;     exit;    end;   Agro:= AgroTest;                            // если есть мобы в базе и нет текущей цели, то   MinDistID:= GetMinDistID;                   // запускаем алгоритм выбора цели   if Agro > 0 then                            // если нас кто-то атакует, то его и выбираем    begin     TargetID:= MobsID[Agro];     PhisicalAttack;                            // берем вражину в таргет     AttackCycle:= 0;     exit;    end;   if ItemsLastIndex > 0 then  // если чего-то валяется на земле, то    begin     InitPickUpMode(true);   // надо дроп подбирать     exit;    end;   if MobsDist[MinDistID] <= Radius then      // иначе ищем ближайшего   #################################################    begin     TargetID:= MobsID[MinDistID];     PhisicalAttack;                           // берем вражину в таргет     AttackCycle:= 0;     exit;    end  end; procedure OnTimerForm (Sender: TObject);           // таймер обновления данных в форме  var   i: integer;  begin   textMyID.text:= inttostr(MyID);                      // обновляем данные в окне   textX.text:= inttostr(MyX);   textY.text:= inttostr(MyY);   textZ.text:= inttostr(MyZ);   textMyHP.text:= inttostr(MyHP);   textMyMaxHP.text:= inttostr(MyMaxHP);   textMyMP.text:= inttostr(MyMP);   textMyMaxMP.text:= inttostr(MyMaxMP);   textMyCP.text:= inttostr(MyCP);   textMyMaxCP.text:= inttostr(MyMaxCP);   textCenterX.text:= inttostr(CenterX);   textCenterY.text:= inttostr(CenterY);   textCenterZ.text:= inttostr(CenterZ);   textRadius.text:= inttostr(Radius);   textTargetID.text:= inttostr(TargetID);   textAttackCycle.text:= inttostr(AttackCycle);   textMobsKilled.text:= inttostr(MobsKilled);   MobsDBscreen.lines.Clear;   for i:=1 to MobsLastIndex do     // выводим БД мобов    begin     if TargetID = MobsID[i] then  MobsDBscreen.lines.add ('-> '+inttostr(i)+' МобID: '+inttostr(MobsID[i])+' дистанция '+inttostr(MobsDist[i]))     else if MobsAgression[i] then MobsDBscreen.lines.add ('<- '+inttostr(i)+' МобID: '+inttostr(MobsID[i])+' дистанция '+inttostr(MobsDist[i]))     else MobsDBscreen.lines.add ('-- '+inttostr(i)+' МобID: '+inttostr(MobsID[i])+' дистанция '+inttostr(MobsDist[i]));    end;   ItemsDBscreen.lines.Clear;       // выводим БД дропа   for i:=1 to ItemsLastIndex do ItemsDBscreen.lines.add ('индекс в БД: '+inttostr(i)+'   объект ID: '+inttostr(Items_ObjectID[i])+'   ID вещи: '+inttostr(Items_ItemID[i]));  end; procedure CreateLabel (text: string);             // процедура автоматизирует создание текстовых меток в форме  var   l: TLabel;  begin   l:= TLabel.Create(panel);   l.caption:=text;   l.parent:=panel;   l.left:=5;   l.top:=15+20*frmParamIndex;   inc(frmParamIndex);  end; function CreateTextBox (text:string) :TEdit;        // функция автоматизирует создание текстовых полей для вывода данных в форме  var   e: TEdit;  begin   e:= TEdit.Create(panel);   e.text:=text;   e.parent:=panel;   e.left:=60;   e.top:=10+20*frmParamIndex;   result:= e;  end; procedure Free; //Вызывается при выключении скрипта begin  MobsDBscreen.free;  ItemsDBscreen.free;  log.free;  frm.free;  ClearDB;  TimerForm.free;  TimerCombat.free;  TimerPickUp.free; end; procedure UserInfo;            // обновление донных о себе  var   i:word;  begin   if InitMode then MyID:=ReadD(18);   MyX:=ReadD(2);   MyY:=ReadD(6);   MyZ:=ReadD(10);   i:=22;   ReadS(i);   if interlude then i:=i+48 else i:=i+44;   MyMaxHP:=ReadD(i);   MyHP:=ReadD(i);   MyMaxMP:=ReadD(i);        // чисто информативно   MyMP:=ReadD(i); //  i:=i+363;               пока не используется //  MyMaxCP:=ReadD(i); //  MyCP:=ReadD(i);  end; procedure StatusUpdate;       // обновление данных о себе  var   i:integer;  begin   for i:=0 to ReadD(6)-1 do    case pck[i*8+10] of     #$09: MyHP:=ReadD(i*8+14);     #$0A: MyMaxHP:=ReadD(i*8+14);     #$0B: MyMP:=ReadD(i*8+14);     #$0C: MyMaxMP:=ReadD(i*8+14); //    #$21: MyCP:=ReadD(i*8+14);          пока не используется //    #$22: MyMaxCP:=ReadD(i*8+14);    end;   if MyMaxHP > 0 then HPlevelProcent:= Round((MyMaxHP/100)*HPMedium);  end; procedure DrinkBottle;          // пьем бутылки и следим за их количеством  begin   if HPBottleCount > 0 then    begin     UseItemObjID(HPBottleObjID);     dec (HPBottleCount);    end;  end; begin  if pck = '' then exit;   if (Connectname=nickname) and FromServer and (pck=HStr('64 64 02 00 00 00 00 00 00')) then   begin    SpoilMode:=false;   end;  if (ConnectName = NickName) and FromServer and (not InitMode) then  // разбор пакетов от сервера в Боевом режиме    case pck[1] of     #$01: begin                             //   MoveToLocation:h(ObjectID)d(CurX)d(CurY)d(CurZ)d(DestX)d(DestY)d(DestZ)            povtor:= TestPovtor(ReadD(2));            if Povtor > 0 then             begin              updateDB(Povtor, ReadD(2), ReadD(18), ReadD(22), ReadD(26), false);             end;           end; //    #$03: ;                             //   CharInfo:d(X)d(Y)d(Z)-(4)h(ObjectID)s(Name)d(Race)d(Sex)d(ClassID)-(4)i(Head)i(RHand)i(LHand)i(Gloves)i(Chest)i(Legs)i(Feet)i(Back)i(LRHand)i(Hair)d(PvPFlag)d(Carma)d(MSpeed)d(PSpeed)d(PvpFlag)d(Karma)d(RunSpeed)d(WalkSpeed)d(SwimRunSpeed)d(SwimWalkSpeed)d(FlRunSpeed)d(FlWalkSpeed)d(FlyRunSpeed)d(FlyWalkSpeed)f(MovementSpeedMultiplier)f(AttackSpeedMultiplier)f(CollisionRadius)f(CollisionHeight)d(HairStyle)d(HairColor)d(Face)d(AccessLevel)s(Title)d(ClanId)d(ClanCrestId)d(AllyId)d(AllyCrestId)d(SiegeFlags)b(Sitting)b(Running)b(InCombat)b(AlikeDead)b(Invisible)b(MountType)b(PrivateStoreType)     #$04: if ReadS(22) = NickName then    //   UserInfo:d(X)d(Y)d(Z)d(Heading)h(ObjectID)s(Name)d(Race)d(Sex)d(ClassID)d(Level)d(Exp)d(STR)d(DEX)d(CON)d(INT)d(WIT)d(MEN)d(MaxHP)d(CurrentHP)d(MaxMP)d(CurrentMP)d(SP)d(CurrentLoad)d(MaxLoad)d(Unknown)d(Under)d(REar)d(LEar)d(Neck)d(RFinger)d(LFinger)d(Head)d(RHand)d(LHand)d(Gloves)d(Chest)d(Legs)d(Feet)d(Back)d(LRHand)d(Hair)i(Under)i(REar)i(LEar)i(Neck)i(RFinger)i(LFinger)i(Head)i(RHand)i(LHand)i(Gloves)i(Chest)i(Legs)i(Feet)i(Back)i(LRHand)i(Hair)d(PAtk)d(PAtkSpd)d(PDef)d(EvasionRate)d(Accuracy)d(CritikalHit)d(MAtk)d(MAtkSpd)d(PAtkSpd)d(MDef)d(PvpFlag)d(Karma)d(RunSpeed)d(WalkSpeed)d(SwimRunSpeed)d(SwimWalkSpeed)d(FlRunSpeed)d(FlWalkSpeed)d(FlyRunSpeed)d(FlyWalkSpeed)f(MovementSpeedMultiplier)f(AttackSpeedMultiplier)f(CollisionRadius)f(CollisionHeight)d(HairStyle)d(HairColor)d(Face)d(AccessLevel)s(Title)d(ClanId)d(ClanCrestId)d(AllyId)d(AllyCrestId)d(IsClanLeader)b(MountType)b(PrivateStoreType)b(DwarvenCraft)d(PkKills)d(PvpKills)b(Cubics)b(Cubics)b(FindPartyMembers)d(AbnormalEffect)b()d(ClanPrivileges)d()d()d()d()d()d()d()b(RecomLeft)b()b(RecomHave)b()            begin             UserInfo;             if MyHP = 0 then             // Проверка не убили ли нас...              begin               SendMsg('Нас убили...');               log.Lines.Add('Нас убили...');               StopGame;              end;            end;     #$05{, #$48}: begin                     //   05= Attack:d(AttackerID)d(TargetID)d(Damage)b(Flags)d(X)d(Y)d(Z)h(Hits)            if ReadD(6) = MyID then             begin              Povtor:= TestPovtor(ReadD(2));//   48= MagicSkillUse              if Povtor = 0 then AddtoDB (ReadD(2), ReadD(15), ReadD(19), ReadD(23), true)                            else UpdateDB(Povtor, ReadD(2), ReadD(15), ReadD(19), ReadD(23), true);             end;           end;     #$06: begin                             //   Die:d(ChaID)            povtor:= TestPovtor(ReadD(2));            if Povtor > 0 then             begin              if MobsID[povtor] = TargetID then               begin                LastKilledMobObjID:=TargetID;                inc (MobsKilled);               // подводим статистику                 SpoilMode:=true;                 TargetID:= 0;               buf:=hstr('2F 2A 00 00 00 00 00 00 00 00');               SendToServerEX(NickName);                // споил надо делать тута               end;              DelDBItem(povtor);             end;           end;     #$0C: if LastKilledMobObjID = ReadD(2) then         //   DropItem:h(PlayerID)h(ObjectID)i(ItemID)d(X)d(Y)d(Z)d(Stackable)d(Count)            begin             AddDroppedItem(ReadD(6), ReadD(10), ReadD(14), ReadD(18), ReadD(22));            end;     #$0D: if TargetID = ReadD(6) then                                              //   GetItem:d(PlayerID)h(ObjectID)d(X)d(Y)d(Z)            begin             TargetID:= 0;            end;     #$0E: if MyID=ReadD(2) then     //   StatusUpdate:h(ObjectID)d(Attributes)            begin             StatusUpdate;             if (MyHP > 0) and (MyHP < HPlevelProcent) then if Wait(time1,DrinkDelay) then DrinkBottle;     // пьем бутылки             if MyHP > HPlevelProcent then time1:=1;             if MyHP = 0 then                                  // Проверка не убили ли нас...              begin               SendMsg('Нас убили...');               log.Lines.Add('Нас убили...');               StopGame;              end;            end;     #$12: begin                                         //   DeleteObject:h(ObjectID)            if LastKilledMobObjID = ReadD(2) then LastKilledMobObjID:= 0             else begin              Povtor:= CheckItems(ReadD(2));              if Povtor <> 0 then DelDroppedItem(Povtor);             end;           end;     #$16: begin                         //   NpcInfo:h(ObjectID)d(NpcTypeID)d(IsAttackable)d(X)d(Y)d(Z)d(Heading)d(Unknown)d(MAtkSpd)d(PAtkSpd)d(RunSpd)d(WalkSpd)d(SwimRunSpd)d(SwimWalkSpd)d(FlRunSpd)d(FlWalkSpd)d(FlyRunSpd)d(FlyWalkSpd)f(ProperMultiplier)f(PAtkSpd)f(CollisionRadius)f(CollisionHeight)d(RHand)d(Unknown)d(LHand)b(Unknown)b(IsRunning)b(IsInCombat)b(IsALikeDead)b(IsSummoned)s(Name)s(Title)            if InMobsList(ReadD(6)) and (ReadD(10)=1) and (pck[121]=#$00) then             begin              Povtor:= TestPovtor(ReadD(2));              if Povtor = 0 then AddtoDB (ReadD(2), ReadD(14), ReadD(18), ReadD(22), false)                            else UpdateDB(Povtor, ReadD(2), ReadD(14), ReadD(18), ReadD(22), false);            end;           end;    end;  if (ConnectName = NickName) and FromClient and (not InitMode) then   // разбор пакетов от клиента в боевом режиме    case pck[1] of //   #$04: {TargetID:= ReadD(2)};          //  Action:h(ObjectID)d(OriginX)d(OriginY)d(OriginZ)b(ActionID)    #$38: UserCommandsCombatMode;         //  Say2:s(Text)d(Type)s(Target)    #$48: begin                           //  ValidatePosition:d(X)d(Y)d(Z)d(Heading)d(Data)            MyX:= ReadD(2);            MyY:= ReadD(6);            MyZ:= ReadD(10);           end;    end;  if (ConnectName = NickName) and FromServer and InitMode then   // разбор пакетов от сервера в режиме настройки бота    case pck[1] of     #$04: if ReadS(22) = NickName then UserInfo; //   UserInfo:d(X)d(Y)d(Z)d(Heading)h(ObjectID)s(Name)d(Race)d(Sex)d(ClassID)d(Level)d(Exp)d(STR)d(DEX)d(CON)d(INT)d(WIT)d(MEN)d(MaxHP)d(CurrentHP)d(MaxMP)d(CurrentMP)d(SP)d(CurrentLoad)d(MaxLoad)d(Unknown)d(Under)d(REar)d(LEar)d(Neck)d(RFinger)d(LFinger)d(Head)d(RHand)d(LHand)d(Gloves)d(Chest)d(Legs)d(Feet)d(Back)d(LRHand)d(Hair)i(Under)i(REar)i(LEar)i(Neck)i(RFinger)i(LFinger)i(Head)i(RHand)i(LHand)i(Gloves)i(Chest)i(Legs)i(Feet)i(Back)i(LRHand)i(Hair)d(PAtk)d(PAtkSpd)d(PDef)d(EvasionRate)d(Accuracy)d(CritikalHit)d(MAtk)d(MAtkSpd)d(PAtkSpd)d(MDef)d(PvpFlag)d(Karma)d(RunSpeed)d(WalkSpeed)d(SwimRunSpeed)d(SwimWalkSpeed)d(FlRunSpeed)d(FlWalkSpeed)d(FlyRunSpeed)d(FlyWalkSpeed)f(MovementSpeedMultiplier)f(AttackSpeedMultiplier)f(CollisionRadius)f(CollisionHeight)d(HairStyle)d(HairColor)d(Face)d(AccessLevel)s(Title)d(ClanId)d(ClanCrestId)d(AllyId)d(AllyCrestId)d(IsClanLeader)b(MountType)b(PrivateStoreType)b(DwarvenCraft)d(PkKills)d(PvpKills)b(Cubics)b(Cubics)b(FindPartyMembers)d(AbnormalEffect)b()d(ClanPrivileges)d()d()d()d()d()d()d()b(RecomLeft)b()b(RecomHave)b()     #$06: if (ReadD(2) = TargetID) and (NpcTypeID_CurrentMob <> 0) then                              //   Die:d(ChaID)            if (NpcTypeID_List[NpcTypeID_CurrentMob] <> 0) then             begin              SendMsg('Моб №' + inttostr(NpcTypeID_CurrentMob) + ' добавлен в базу');              log.Lines.Add('Моб №' + inttostr(NpcTypeID_CurrentMob) + ' добавлен в базу');              inc(NpcTypeID_List_Count);              NpcTypeID_CurrentMob:= 0;              TargetID:= 0;             end;     #$16: if (ReadD(2) = TargetID) and (NpcTypeID_CurrentMob <> 0) then NpcTypeID_List[NpcTypeID_CurrentMob]:= ReadD(6);//NpcInfo:h(ObjectID)d(NpcTypeID)d(IsAttackable)d(X)d(Y)d(Z)d(Heading)d(Unknown)d(MAtkSpd)d(PAtkSpd)d(RunSpd)d(WalkSpd)d(SwimRunSpd)d(SwimWalkSpd)d(FlRunSpd)d(FlWalkSpd)d(FlyRunSpd)d(FlyWalkSpd)f(ProperMultiplier)f(PAtkSpd)f(CollisionRadius)f(CollisionHeight)d(RHand)d(Unknown)d(LHand)b(Unknown)b(IsRunning)b(IsInCombat)b(IsALikeDead)b(IsSummoned)s(Name)s(Title)     #$1B: begin            InventoryCreate;  // Инвентарь            HPBottleObjID:= getinv(HPBottleID, 2,1);            HPBottleCount:= getinv(HPBottleID, 2,3);           end;     #$27: begin            InventoryUpdate;            HPBottleCount:= getinv(HPBottleID, 2,3);           end;    end;  if (ConnectName = NickName) and FromClient and InitMode then      // разбор пакетов от клиента в режиме настройки бота    case pck[1] of     #$04: TargetID:= ReadD(2);       //  Action:h(ObjectID)d(OriginX)d(OriginY)d(OriginZ)b(ActionID)     #$38: UserCommandsInitMode;      //  Say2:s(Text)d(Type)s(Target)     #$48: begin                      //  ValidatePosition:d(X)d(Y)d(Z)d(Heading)d(Data)            MyX:= ReadD(2);            MyY:= ReadD(6);            MyZ:= ReadD(10);           end;    end; end.
VismuT вне форума   Ответить с цитированием
За это сообщение VismuT нажился 3 спасибками от: