Скриптинг Форум посвещенный созданию скриптов для L2PacketHack
13.11.2008, 04:31
#1
Новичок
Регистрация: 29.09.2008
Сообщений: 14
Сказал Спасибо: 3
Имеет 3 спасибок в 1 сообщении
помогите с доработкой
доброго время суток, собственно есть хороший скрипт "Бот - локомотив от Alexus" решил его немного доработать включив в него спойл. Получилось вот что
delphi Код:
{#############################################################################
Бот - локомотив от Alexus
версия : 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 : 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 ;
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
buf:=hstr( '2F FE 00 00 00 00 00 00 00 00' ) ;
WriteD( TargetID) ;
WriteD( MyX) ;
WriteD( MyY) ;
WriteD( MyZ) ;
WriteC( 0 ) ;
SendToServerEx( NickName) ;
SendToServerEX( 'HiliH' ) ;
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 ( 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) ; // подводим статистику
TargetID:= 0 ;
buf:=hstr( '2F 2A 00 00 00 00 00 00 00 00' ) ;
SendToServerEX( 'HiliH' ) ;
// споил надо делать тута
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 .
собственно доработка состояла в добавлении нескольких строк, на спойл:
delphi Код:
procedure PhisicalAttack; // команда атаки
begin
buf:=#$04 ; //action
WriteD( TargetID) ;
WriteD( MyX) ;
WriteD( MyY) ;
WriteD( MyZ) ;
WriteC( 0 ) ;
buf:=hstr( '2F FE 00 00 00 00 00 00 00 00' ) ;
SendToServerEx( NickName) ;
SendToServerEX( 'HiliH' ) ;
end ;
На свип соответственно тут
delphi Код:
#$06 : begin // Die:d(ChaID)
povtor:= TestPovtor( ReadD( 2 ) ) ;
if Povtor > 0 then
begin
if MobsID[povtor] = TargetID then
begin
LastKilledMobObjID:=TargetID;
inc ( MobsKilled) ; // подводим статистику
TargetID:= 0 ;
buf:=hstr( '2F 2A 00 00 00 00 00 00 00 00' ) ;
SendToServerEX( 'HiliH' ) ;
// споил надо делать тута
end ;
DelDBItem( povtor) ;
end ;
end ;
Собственно он стал спойлить и свипать убитых мобов, но, сам он не начинает атаковать мобов и перестал поднимать дроп, помогите разобратся в чем трабла. Прошу строго не судить токо начинаю пытаться разобратся с языком
Последний раз редактировалось QaK, 13.11.2008 в 09:50 .
Причина: юзай правильные теги оформления кода
13.11.2008, 09:58
#2
Рыцарь
Регистрация: 28.09.2007
Сообщений: 1,558
Сказал Спасибо: 71
Имеет 351 спасибок в 244 сообщенях
delphi Код:
procedure PhisicalAttack; // команда атаки
begin
buf:=#$04 ; //action
WriteD( TargetID) ;
WriteD( MyX) ;
WriteD( MyY) ;
WriteD( MyZ) ;
WriteC( 0 ) ;
SendToServerEx( NickName) ;
buf:=hstr( '2F FE 00 00 00 00 00 00 00 00' ) ;
SendToServerEX( 'HiliH' ) ;
end ;
попробуй так
Последний раз редактировалось QaK, 13.11.2008 в 10:22 .
13.11.2008, 12:13
#3
Новичок
Регистрация: 29.09.2008
Сообщений: 14
Сказал Спасибо: 3
Имеет 3 спасибок в 1 сообщении
СЧпасибо, заработало, сегодня попробую еще сделать версию с манором.
13.11.2008, 13:09
#4
Рыцарь
Регистрация: 28.09.2007
Сообщений: 1,558
Сказал Спасибо: 71
Имеет 351 спасибок в 244 сообщенях
тема клоуз.
Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
Часовой пояс GMT +4, время: 14:25 .
vBulletin style designed by
MSC Team .
Powered by vBulletin® Version 3.6.11
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод:
zCarot
Вы хотите чувствовать себя в безопасности? чоп Белган обеспечит её!