L2PacketHack Форум программы L2PacketHack, всё что с ней связано находится тут.
Правила раздела! Категорически запрещено:
* Просить пакеты/скрипты на шмот/адену/другие вещи;
* Просить (помочь) взломать/сломать сервак/аккаунт или раздеть/наказать кого-то на любом серваке;
* Просить научить работать с программой, если не понимаете элементарных вещей в отношениях клиент-сервер (так как, если вы их понимаете, то вопросов по основным возможностям программы быть недолжно);
* Все посты не удовлетворяющие этим запретам, а так же не относящиеся к теме будут удаляться при первой возможности.
* Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы.
* Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.
* Данные запреты неподлежат обсуждению.
Обсуждение багов Lineage ЗАПРЕЩЕНО!
13.04.2009, 12:59
#31
Рыцарь
Регистрация: 25.02.2008
Адрес: г.Волгоград
Сообщений: 2,009
Сказал Спасибо: 1,285
Имеет 1,458 спасибок в 793 сообщенях
Цитата:
Сообщение от
DashKAaa
хмм, это с пакетами отредактированный ?
домой приду проверю... просто вчера пробовал все передал, но команды из чата не воспринимал (
Да, у меня работает, пробовал человеком-воином в талкин исланде.
13.04.2009, 13:33
#32
Заблокирован
Регистрация: 10.03.2008
Адрес: Тула
Сообщений: 1,098
Сказал Спасибо: 188
Имеет 108 спасибок в 60 сообщенях
если работает то спасибо те, сравню со своим изменением погляжу в чем ошибка.. но я вроде подозреваю в чем.. в процедуре вывода сообщения, пакет стоит не тот... хотя ставил его как в с4...
а споил, буфф, пакеты так же придется менять? или в них достаточно поменять пакет на захват инветнаря, что бы обновить чар инфо? т.е не лечит он вроде по той самой причине т.к не видит парти игрока хп...
13.04.2009, 13:58
#33
Рыцарь
Регистрация: 25.02.2008
Адрес: г.Волгоград
Сообщений: 2,009
Сказал Спасибо: 1,285
Имеет 1,458 спасибок в 793 сообщенях
Цитата:
Сообщение от
DashKAaa
если работает то спасибо те, сравню со своим изменением погляжу в чем ошибка.. но я вроде подозреваю в чем.. в процедуре вывода сообщения, пакет стоит не тот... хотя ставил его как в с4...
а споил, буфф, пакеты так же придется менять? или в них достаточно поменять пакет на захват инветнаря, что бы обновить чар инфо? т.е не лечит он вроде по той самой причине т.к не видит парти игрока хп...
Я все пакеты не проверял, но судя по тому что пакет ItemList форматом от грации а с айди от интерлюда, то наверное и другие такие же.
13.04.2009, 20:06
#34
Заблокирован
Регистрация: 10.03.2008
Адрес: Тула
Сообщений: 1,098
Сказал Спасибо: 188
Имеет 108 спасибок в 60 сообщенях
Цитата:
Сообщение от
NLObP
Пробуйте бота:
Бот Алексус для Абисса
delphi Код:
Const ProgramName =
'Бот - локомотив от Alexus ' +
'версия : 0.5.2 (for Abyss) ' +
'дата: 13.04.09' ;
{#############################################################################
Описание:
Бот для соло-кача в принципе любого война. По функциональности (в режиме кача) это еще не Волкер, но скрипт уже довольно умный :)
Охотиться только на заданных мобов.
Возможности:
- запоминает центр и радиус кача
- запоминает список мобов на которых надо охотиться!
- запоминает и затем подбирает дроп, упавший с убитых им мобов
- умеет лечиться банками (тип банки легко настраивается), ведется учет количества оставшихся банок
- управляется из окна чата в самом клиенте
- имеет окно для вывода всех параметров и статистики
- если моб по какой-то причине стал недосягаемым (стоит за деревом), то через 1 мин БОТ переключится на другого моба.
- если бот умирает, то не палимся и прекращаем рыпаться...(скоро появиться возможность логаута)
- пьет баф-банки
- работает под РУ-ОФФ Gracia, но для этого нужно обойти щит-консоль
- умеет спойлить (функция новая, нужно тестить)
Недостатки: (со временем будет исправлено)
- бот не умеет обходить препядствия
История версий:
0.1 - самое начало :)
0.2 - куча глюков, первая рабочая версия!
0.3 - первая стабильная безглючная версия, с минимальной функциональностью (самая стабильная, но очень простая)
0.4 - изменения:
- радиус кача можно задать в секции настройки
- бот теперь сразу видит всю локацию с самого запуска скрипта
- автоопределение размера инвентаря
- ID мобов можно теперь задавать в секции настройки
- ускорен процесс добавление мобов через клиент (теперь их не надо гасить)
- отключена ф-ция автоопределения своего ID и инвентаря, по этому запускать теперь бот надо до запуска клиента
- обновлено окно вывода информации (теперь его нельзя случайно закрыть!)
- на форму добавлены кнопки управления
- добавлена кнопка "Init" в окно управления, теперь бота можно запускать в любом месте, затем нажать эту кнопку
- добавлен механизм глотания баф-банок
- оптимизирован алгоритм выбора ближайшего моба
- скрипт доработан для новых версий пакетхака (данная версия разработана под пакетхак версии 3.4.1.69)
- в режиме кача, при отсутствии мобов в радиусе, бот возвращается в центр кача
- устранена ошибка, связянная с неправильным распознованием пакета 01 - MoveToLocation
0.5 - модификация под РУ-ОФФ Gracia
- добавлен споил
- убрана ошибка, вылезающая после нажатия кнопки Init
- немного подправлен алгоритм работы с инвентарем
Инструкция:
1. Внимательно НАСТРАИВАЕМ параметры в секции настройки
(90% ошибок и последующих глюков в скрипте вылезает именно отсюда!!!), жмем кнопку "Сохранить"
2. Запускаем ПакетХак, запускаем скрипт, запускаем игрового клиента.
либо запускаем скрипт после захода в игру, и жмем кнопку на форме "Init"
3. Добираемся до места кача
4. Выбираем в таргет моба на которого хотим охотится и отправляем в общий чат-> 1
5. Выбираем следующего моба отправляем в общий чат цифру 2, и т.д. можно выбрать до 10 разных тварей.
6. Либо просто в секции настройки задаем ID мобов
7. Становимся в центр кача и отправляем в общий чат-> pos , если все правильно то в чате будет выдано сообщение, что координаты заданы.
8. Бежим к краю радиуса кача и отправляем в общий чат-> dist, в чате вылезет сообщение от системы, что радиус задан.
9. Если радиус кача задан в секции настройки, то п.7 и 8 можно пропустить!!! становимся примерно в центр кача и отправляем в общий чат-> start ,
если все сделано верно, то будет выдано соответствующее сообщение.
10.Если бот поймал моба в таргет и побежал его атаковать, то можно свернуть окно игры
и смотреть на информационное окно скрипта.
В процессе кача, в общий чат можно посылать следующие управляющие команды:
pause - пауза, можно приостановить бота, повторная комманда pause запустит бота
stop - срочная остановка бота, и сброс всех настроек, повторный запуск возможен командой start
Также можно управлять ботом одноименными кнопками с формы.
#############################################################################}
//################### Сеция настройки бота ############################################
NickName = 'NLObP' ; // Твой ник в игре
CharNumber = 0 ; // если больше одного перса на аккаунте, то задаем его порядковый номер, нумерация начинается с нуля.
Radius_Kacha = 2000 ; // Радиус кача, если 0 - то задавать вручную через клиента (изменять от 100 до 9999). Проверил на практике, что максимум не более 2000.
Spoil = false ; // Споил false - откл, true - вкл. (только для гномов-спойлеров)
//-------------------------------------------------------------------------------------
HPLevel = 70 ; // Уровень жизни в %, при котором начинаем глотать банки
HPBottleID = 0 ; // ItemID 1060=Lesser Healing Potion; 1061=Healing Potion; 1539=Greater Healing Potion;
DrinkDelay = 14 ; // минимальное время задержки повторного питься HP-бутылки (10 - 20 сек).
//---------------------------------------------------------------------------------------
Bottle_1 _ID = 0 ; // ID номера баф-банок, 6036=Greater Magic Haste Potion, 6035=Magic Haste Potion, 1374=Greater Haste Potion, 1062=Haste Potion, 734=Haste Potion
Bottle_2 _ID = 0 ; // если 0 - то не использовать. 1375=Greater Swift Attack Potion, 735=Potion of Alacrity
Bottle_Interval = 19 ; // Время задержки повторного использования бутылей в минутах (изменять от 1 до 100)
//----------------------------------------------------------------------------------------
//############# Секция расширенной настройки для опытных ботоводеров :) ###################################
TimerCombat_Interval = 500 ; // частота срабатывания таймера атаки в милисекундах, чем меньше это число, тем быстрее бот будет думать.
TimerPickUp_Interval = 500 ; // частота срабатывания таймера сбора дропа, чем меньше это число, тем быстрее бот будет думать.
TimerForm_Interval = 2500 ; // частота срабатывания таймера обновления формы, чем меньше это число, тем быстрее будут обновляться данные в форме.
Attack_Time = 45 ; // Время на убивание моба в секундах.
PickUp_Time = 15 ; // Врямя на поднятие дропа в секундах.
Vertical = 1000 ; // Вертикальный радиус кача
//---------------------------------------------------------------------------------------
NpcTypeID1 = 0 ; // Если знаем, то задаем Type ID мобов, на которых будем охотиться
NpcTypeID2 = 0 ; // Если здесь одни нули, то задавать мобов будем через клиента
NpcTypeID3 = 0 ; // Для интерлюда задаем в формате 102xxxx , где xxxx - ID моба
NpcTypeID4 = 0 ; // Для С4 в формате 100хххх , где xxxx - ID моба
NpcTypeID5 = 0 ; // Для Gracia формат пока не смотрел...
NpcTypeID6 = 0 ;
NpcTypeID7 = 0 ;
NpcTypeID8 = 0 ;
NpcTypeID9 = 0 ;
NpcTypeID10 =0 ;
//########################################################################################
NpcTypeID_List_Razmer = 10 ; // Размер списка мобов (не трогать!)
OX = 1 ; OY = 2 ; OZ= 3 ; // Служебные константы
maximumItems = 500 ; // Размер базы мобов и дропа.
OblastVidimosti = 500000 ; // (не трогать!!!) Область видимости объектов (изменять от 1000 до 500000).
InvRazmer = 249 ; // Размер инвентаря (не трогать)
var
InitMode, RestartMode, PickUpMode : boolean ;
//-------------------------------------- БД --------------------------------------------------
MobsObjID : array [1 ..maximumItems ] of integer ; // ID моба
MobsNpcTypeID : array [1 ..maximumItems ] of integer ; // Тип моба
MobsDist : array [1 ..maximumItems ] of integer ; // Расстояние от центра кача до моба
MobsXYZ : array [1 ..maximumItems , 1 ..3 ] of integer ; // Координаты
MobsIsAttackable : array [1 ..maximumItems ] of boolean ; // Можно ли моба атаковать
MobsAgression : array [1 ..maximumItems ] of boolean ; // Моб атакует меня или стоит в сторонке...
MobsUpdated : 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)
CurrentInvRazmer : integer ;
HPBottleObjID, HPBottleCount : integer ; // ObjID и количество HP-бутылей
Bottle_1 _ObjID, Bottle_1 _Count : integer ;
Bottle_2 _ObjID, Bottle_2 _Count : integer ;
TargetID, LastKilledMobObjID : integer ; // Текущая цель, последний убитый моб
MobsKilled : integer ; // счетчик убитых мобов
CenterX, CenterY, CenterZ : integer ; // Центр кача
CenterFixed : boolean ;
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;
btnInit, btnStart, btnStop, btnPause: TButton;
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, textMobsLastIndex, textMobsKilled: TEdit;
textHPBottleCount, textBottle_1 _Count, textBottle_2 _Count: TEdit;
cbFilterRadius : TCheckBox; l1: Tlabel;
//----------------------------------------------------------
TimerForm, TimerCombat, TimerPickUp, TimerBafBanka, TimerCheckDB : TTimer; // таймеры
time1: integer ;
Calculated_AttackTime, Calculated_PickUpTime : integer ;
AttackCycle: integer ; // Цикл атаки
Spoiled: boolean ;
//##############################################################################################
procedure Init; //Вызывается при включении скрипта
var
i,n : integer ;
begin
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 ;
Bottle_1 _ObjID:= 0 ;
Bottle_1 _Count:= 0 ;
Bottle_2 _ObjID:= 0 ;
Bottle_2 _Count:= 0 ;
InitMode:= true ;
RestartMode:= false ;
MobsLastIndex:= 0 ;
for i:=1 to maximumItems do // Очищаем базу
begin
MobsObjID[i]:= 0 ;
MobsNpcTypeID[i]:=0 ;
MobsDist[i]:= 0 ;
MobsXYZ[i, OX]:= 0 ;
MobsXYZ[i, OY]:= 0 ;
MobsXYZ[i, OZ]:= 0 ;
MobsIsAttackable[i]:= false ;
MobsAgression[i]:= false ;
MobsUpdated[i]:=false ;
end ;
for i:=0 to InvRazmer do for n:=0 to 9 do Inventory[i, n]:= 0 ;
CurrentInvRazmer:=0 ;
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;
TimerBafBanka:=TTimer.Create ( nil ) ;
TimerBafBanka.OnTimer :=@OnTimerBafBanka;
TimerBafBanka.enabled :=false ;
TimerBafBanka.interval := 15000 ;
TimerCheckDB:=TTimer.Create ( nil ) ;
TimerCheckDB.OnTimer :=@OnTimerCheckDB;
TimerCheckDB.enabled :=true ;
TimerCheckDB.interval := 20 *60 *1000 ; // раз в 20 минут
frmParamIndex:=0 ; // создаем контролы в форме
frm:= TForm.Create ( nil ) ;
frm.Caption := ProgramName;
frm.BorderStyle := bsDialog;
frm.Position := poScreenCenter;
frm.Width :=650 ;
frm.Height :=700 ;
frm.OnClose := @FormClose;
MobsDBscreen:=TMemo.Create ( frm) ;
MobsDBscreen.parent :=frm;
MobsDBscreen.ReadOnly :=true ;
MobsDBscreen.ScrollBars :=0 ;
MobsDBscreen.Top :=157 ;
MobsDBscreen.Width :=457 ;
MobsDBscreen.Height :=385 ;
ItemsDBscreen:=TMemo.Create ( frm) ;
ItemsDBscreen.parent :=frm;
ItemsDBscreen.ReadOnly :=true ;
ItemsDBscreen.ScrollBars :=0 ;
ItemsDBscreen.Top :=1 ;
ItemsDBscreen.Width :=300 ;
ItemsDBscreen.Height :=155 ;
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 ( 'Лог...' ) ;
btnInit:= TButton.Create ( frm) ;
btnInit.Name := 'btnInit' ;
btnInit.Parent := frm;
btnInit.SetBounds ( 370 , 10 , 75 , 25 ) ;
btnInit.Caption := 'Init' ;
btnInit.OnClick := @BtnInit_Click;
btnStart:= TButton.Create ( frm) ;
btnStart.Name := 'btnStart' ;
btnStart.Parent := frm;
btnStart.SetBounds ( 370 , 40 , 75 , 25 ) ;
btnStart.Caption := 'Start' ;
btnStart.OnClick := @btnStart_Click;
btnStop:= TButton.Create ( frm) ;
btnStop.Name := 'btnStop' ;
btnStop.Parent := frm;
btnStop.SetBounds ( 370 , 70 , 75 , 25 ) ;
btnStop.Caption := 'Stop' ;
btnStop.OnClick := @btnStop_Click;
btnPause:= TButton.Create ( frm) ;
btnPause.Name := 'btnPause' ;
btnPause.Parent := frm;
btnPause.SetBounds ( 370 , 100 , 75 , 25 ) ;
btnPause.Caption := 'Pause' ;
btnPause.OnClick := @btnPause_Click;
l1:= TLabel.Create ( frm) ;
l1.caption :='Фильтры:' ;
l1.parent :=frm;
l1.SetBounds ( 5 , 547 , 97 , 17 ) ;
cbFilterRadius := TCheckBox.Create ( frm) ;
cbFilterRadius.Name := 'cbFilterRadius' ;
cbFilterRadius.Parent := frm;
cbFilterRadius.SetBounds ( 60 , 545 , 97 , 17 ) ;
cbFilterRadius.Caption := 'Радиус' ;
// cbFilterRadius.OnClick := @CheckBoxFilterClick;
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( 'Цикл атаки:' ) ;
textMobsLastIndex:= CreateTextBox( 'MobsLastIndex' ) ;
CreateLabel( 'Мобов в БД:' ) ;
textMobsKilled:= CreateTextBox( 'MobsKilled' ) ;
CreateLabel( 'Убито моб:' ) ;
inc ( frmParamIndex) ;
textHPBottleCount:= CreateTextBox( 'HPBottleCount' ) ;
CreateLabel( 'HP бутылей:' ) ;
textBottle_1 _Count:= CreateTextBox( 'Bottle_1_Count' ) ;
CreateLabel( 'Баф-Банки 1:' ) ;
textBottle_2 _Count:= CreateTextBox( 'Bottle_2_Count' ) ;
CreateLabel( 'Баф-Банки 2:' ) ;
ClearDB;
frm.Show ; // выводим форму на экран
buf:=#$6E;
SendToServerEx( NickName) ;
end ;
procedure btnPause_Click( Sender: TButton) ;
begin
PauseGame;
end ;
procedure btnStop_Click( Sender: TButton) ;
begin
StopGame;
end ;
procedure btnStart_Click( Sender: TButton) ;
begin
StartGame;
end ;
procedure BtnInit_Click( Sender: TButton) ;
begin
RestartMode:= true ;
buf:= #$57 ; // авто релогин
// buf:= #$0F; // принудительно вызываем пакеты инвентаря и userinfo
SendToServerEx( NickName) ;
end ;
procedure AddtoNpcTypeID_List ( NpcTypeID: integer ) ;
begin
inc ( NpcTypeID_List_Count) ;
NpcTypeID_List[NpcTypeID_List_Count]:= NpcTypeID;
end ;
procedure ClearDB; // Очистка БД
var // Надо все занулять, иначе там хрень всякая вылезает или старые данные
i : integer ;
begin
ItemsLastIndex:= 0 ; // Очищаем переменные
TargetID:= 0 ;
LastKilledMobObjID:= 0 ;
MobsKilled:= 0 ;
CenterX:= 0 ;
CenterY:= 0 ;
CenterZ:= 0 ;
CenterFixed:= false ;
Radius:= Radius_Kacha;
TimerBafBanka.interval := 15000 ;
AttackCycle:= 0 ;
Spoiled:= false ;
NpcTypeID_List_Count:= 0 ;
if NpcTypeID1 <> 0 then AddtoNpcTypeID_List ( NpcTypeID1) ;
if NpcTypeID2 <> 0 then AddtoNpcTypeID_List ( NpcTypeID2) ;
if NpcTypeID3 <> 0 then AddtoNpcTypeID_List ( NpcTypeID3) ;
if NpcTypeID4 <> 0 then AddtoNpcTypeID_List ( NpcTypeID4) ;
if NpcTypeID5 <> 0 then AddtoNpcTypeID_List ( NpcTypeID5) ;
if NpcTypeID6 <> 0 then AddtoNpcTypeID_List ( NpcTypeID6) ;
if NpcTypeID7 <> 0 then AddtoNpcTypeID_List ( NpcTypeID7) ;
if NpcTypeID8 <> 0 then AddtoNpcTypeID_List ( NpcTypeID8) ;
if NpcTypeID9 <> 0 then AddtoNpcTypeID_List ( NpcTypeID9) ;
if NpcTypeID10<> 0 then AddtoNpcTypeID_List ( NpcTypeID10) ;
if NpcTypeID_List_Count = 0 then
for i:=1 to NpcTypeID_List_Razmer do NpcTypeID_List[i]:= 0 ;
NpcTypeID_CurrentMob:= 0 ;
for i:=1 to maximumItems do // Очищаем базу
begin
Items_ObjectID[i]:= 0 ;
Items_ItemID[i]:= 0 ;
Items_XYZ[i, OX]:= 0 ;
Items_XYZ[i, OY]:= 0 ;
Items_XYZ[i, OZ]:= 0 ;
end ;
btnStop.enabled :=false ;
btnPause.enabled := false ;
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
offset:= 76 ;
CurrentInvRazmer:=ReadH( 4 ) ;
for i:=0 to InvRazmer do
if i < CurrentInvRazmer then begin
Inventory[i,0 ]:=ReadH( i*offset+6 ) ; // itemType1
Inventory[i,1 ]:=ReadD( i*offset+8 ) ; // ObjectId
Inventory[i,2 ]:=ReadD( i*offset+12 ) ; // ItemID
Inventory[i,3 ]:=ReadD( i*offset+20 ) ; // count
Inventory[i,4 ]:=ReadH( i*offset+24 ) ; // itemType2
Inventory[i,5 ]:=ReadH( i*offset+26 ) ; // CustType1
Inventory[i,6 ]:=ReadH( i*offset+28 ) ; // isEquipped
Inventory[i,7 ]:=ReadD( i*offset+30 ) ; // BodyPart
Inventory[i,8 ]:=ReadH( i*offset+34 ) ; // EnchantLevel
Inventory[i,9 ]:=ReadH( i*offset+36 ) ; // CustType2
end else
for k:=0 to 9 do Inventory[i,k]:=0 ; // забиваем нулями
end ;
procedure InventoryUpdate;
var
i,j,k, offset: integer ;
begin
offset:= 82 ;
for j:=0 to ( ReadH( 2 ) -1 ) do
begin
case pck[j*offset+4 ] of
#$01 : k:=0 ; // add item, запишет на пустую ячейку
#$02 : k:=ReadD( j*offset+8 ) ; // mod item
#$03 : begin // remove item, обнулит ячейки удаленного предмета
k:=ReadD( j*offset+8 ) ;
for i:=0 to InvRazmer do if ( Inventory[i,1 ]=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*offset+6 ) ; // itemType1
Inventory[i,1 ]:=ReadD( j*offset+8 ) ; // ObjectId
Inventory[i,2 ]:=ReadD( j*offset+12 ) ; // ItemID
Inventory[i,3 ]:=ReadD( j*offset+20 ) ; // count
Inventory[i,4 ]:=ReadH( j*offset+24 ) ; // itemType2
Inventory[i,5 ]:=ReadH( j*offset+26 ) ; // CustType1
Inventory[i,6 ]:=ReadH( j*offset+28 ) ; // isEquipped
Inventory[i,7 ]:=ReadD( j*offset+30 ) ; // BodyPart
Inventory[i,8 ]:=ReadH( j*offset+34 ) ; // EnchantLevel
Inventory[i,9 ]:=ReadH( j*offset+36 ) ; // 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 CurrentInvRazmer 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 ) ; //Использовать предмет с заданным ItemObjID
begin
buf:=#$19 ;
WriteD( ItemObjID) ;
WriteD( 0 ) ;
SendToServerEx( NickName) ;;
end ;
//############################################################################################
function rastoyanie( NpcX, NpcY, NpcZ : integer ) : longint ; // вычисление растояния между 2 точками
var
dx,dy,dz : integer ;
summa : longint ;
begin
try
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 + OblastVidimosti; // добавляем коррекцию по вертикали
except
sendmsg( 'Ошибка вычисления расстояния' ) ;
sendmsg( 'dx= ' + inttostr ( dx) ) ;
sendmsg( 'dy= ' + inttostr ( dy) ) ;
sendmsg( 'dz= ' + inttostr ( dz) ) ;
sendmsg( 'summa= ' + inttostr ( summa) ) ;
result := OblastVidimosti;
end ;
end ;
function RastoyanieToMe( NpcX, NpcY : integer ) : integer ; // вычисление растояния между 2 точками
var
dx,dy, summa : integer ;
begin
dx:= NpcX-MyX;
dy:= NpcY-MyY;
summa:= dx*dx+dy*dy; // мне кажется, что так будет быстрее считаться
if summa = 0 then result:= 0 else result:= Round ( sqrt ( summa) ) ; // обход возможной ошибки, если моб стоит прямо в центре кача
end ;
procedure AddDroppedItem ( ObjID, ItemID, X, Y, Z: integer ) ; // Процедура добавляет дропнутую вещь в БД
begin
if ItemsLastIndex = maximumItems then ItemsLastIndex:=0 ; // обход переполнения базы предметов
inc ( ItemsLastIndex) ;
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, TypeID, x,y,z : integer ; IsAttackable : boolean ) ; // Процедура добавляет в БД нового моба
var
dist: integer ;
begin
if ( not initmode) then dist:= rastoyanie ( x,y,z) else dist := OblastVidimosti; // вычиляем расстояние от центра кача до моба
if dist > ( OblastVidimosti) then exit ; // если моб слишко далеко то ничего не делаем
inc ( MobsLastIndex) ; // увеличиваем размер БД
// log.Lines.Add('Моб добавлен, индекс в БД:'+ inttostr(MobsLastIndex));
// if agression then log.Lines.Add('На нас напала какая-то вражина.');
MobsObjID[MobsLastIndex]:= id; // Записываем моба
MobsNpcTypeID[MobsLastIndex]:= TypeID;
MobsDist[MobsLastIndex]:= dist;
MobsXYZ[MobsLastIndex, OX]:= x;
MobsXYZ[MobsLastIndex, OY]:= y;
MobsXYZ[MobsLastIndex, OZ]:= z;
MobsIsAttackable[MobsLastIndex]:= IsAttackable;
MobsAgression[MobsLastIndex]:= false ;
MobsUpdated[MobsLastIndex]:= true ;
end ;
procedure UpdateDB ( i, x,y,z : integer ; agression : boolean ) ; // Процедура обновляет данные в БД по мобу
var
dist: integer ;
begin
if ( not initmode) then dist:= rastoyanie ( x,y,z) else dist := OblastVidimosti;
if dist > ( 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;
if ( not MobsAgression[i]) then MobsAgression[i]:= agression;
MobsUpdated[i]:= true ;
end ;
end ;
procedure DelDBItem ( i: integer ) ; // процедура удалаяет моба из БД
begin
// log.Lines.Add('Моб удален, индекс в БД: '+ inttostr(i));
MobsObjID[i]:= 0 ;
MobsNpcTypeID[i]:= 0 ;
MobsDist[i]:= 0 ;
MobsXYZ[i, OX]:= 0 ;
MobsXYZ[i, OY]:= 0 ;
MobsXYZ[i, OZ]:= 0 ;
MobsAgression[i]:= false ;
MobsIsAttackable[i]:= false ;
MobsUpdated[i]:= false ;
if i < MobsLastIndex then // если надо, производим сдвиг данных в массивах
begin
MobsObjID[i]:= MobsObjID[MobsLastIndex];
MobsNpcTypeID[i]:= MobsNpcTypeID[MobsLastIndex];
MobsDist[i]:= MobsDist[MobsLastIndex];
MobsXYZ[i, OX]:= MobsXYZ[MobsLastIndex, OX];
MobsXYZ[i, OY]:= MobsXYZ[MobsLastIndex, OY];
MobsXYZ[i, OZ]:= MobsXYZ[MobsLastIndex, OZ];
MobsIsAttackable[i]:= MobsIsAttackable[MobsLastIndex];
MobsAgression[i]:= MobsAgression[MobsLastIndex];
MobsUpdated[i]:= MobsUpdated[MobsLastIndex];
end ;
dec ( MobsLastIndex) ; // уменьшаем размер БД
end ;
procedure DelDroppedItem ( i: 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
begin
Items_ObjectID[i]:= Items_ObjectID[ItemsLastIndex];
Items_ItemID[i] := Items_ItemID[ItemsLastIndex];
Items_XYZ[i, OX]:= Items_XYZ[ItemsLastIndex, OX];
Items_XYZ[i, OY]:= Items_XYZ[ItemsLastIndex, OY];
Items_XYZ[i, OZ]:= Items_XYZ[ItemsLastIndex, 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 MobsObjID[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_to_CL( msg:string ) ; // отправка системных сообщений клиенту
begin
buf:=#$4A;
WriteD( 0 ) ;
WriteD( 10 ) ;
WriteS( '' ) ;
WriteS( msg) ;
SendToClientEx( NickName) ;
end ;
procedure OnTimerCheckDB ( Sender: TObject ) ;
var
i: integer ;
begin
i:=0 ;
while i <= MobsLastIndex do
begin
inc ( i) ;
if MobsUpdated[i] then MobsUpdated[i]:=false
else
begin
DelDBItem( i) ;
dec ( i) ;
end ;
end ;
end ;
procedure PrepareDB;
var
i: integer ;
//dist : double;
begin
i:=0 ;
while i <= MobsLastIndex do
begin
inc ( i) ;
if InMobsList( MobsNpcTypeID[i]) then MobsIsAttackable[i]:= true ;
MobsDist[i] := rastoyanie ( MobsXYZ[i, OX], MobsXYZ[i, OY], MobsXYZ[i, OZ]) ;
if MobsDist[i] >= OblastVidimosti then
begin
// DelDBItem(i);
// dec(i);
end ;
end ;
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
PrepareDB;
SendMsg_to_CL( 'Все начальные параметры заданы и проверены!' ) ;
log.Lines .Add ( 'Все начальные параметры заданы и проверены!' ) ;
result:= true ;
end
else
begin
SendMsg_to_CL( 'Ошибка задания начальных параметров!' ) ;
log.Lines .Add ( 'Ошибка задания начальных параметров!' ) ;
result:= false ;
end ;
end ;
procedure UserCommands; // комманды пользователя
var
i: integer ;
begin // если комманда обработана удачно, то в чат сообщение не попадет, а будет выдано системное сообщение прямо в клиент
if InitMode then case ( ReadS( 2 ) ) of
'pos' : if MyX <> 0 then // центр кача
begin
CenterX:= MyX;
CenterY:= MyY;
CenterZ:= MyZ;
CenterFixed:= true ;
SendMsg_to_CL( 'Центр кача задан успешно!' ) ;
log.Lines .Add ( 'Центр кача задан успешно!' ) ;
pck:='' ;
end ;
'dist' : if ( CenterX <> 0 ) and ( MyX <> 0 ) then // радиус кача
begin
CenterFixed:= true ;
Radius:= rastoyanie ( MyX,MyY,MyZ) ;
SendMsg_to_CL( 'Радиус кача задан успешно' ) ;
SendMsg_to_CL( 'R= ' + inttostr ( Radius) ) ;
log.Lines .Add ( 'Радиус кача задан успешно, R = ' + inttostr ( Radius) ) ;
pck:='' ;
end ;
'reset' : begin // сброс параметров
ClearDB;
SendMsg_to_CL( 'БД очищена, введите заново все параметры' ) ;
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_to_CL( 'Добавлять мобов можно тока по очереди 1, 2, 3...' ) ;
pck:='' ;
exit ;
end ;
NpcTypeID_CurrentMob:= strtoint ( ReadS( 2 ) ) ;
SendMsg_to_CL( 'Добавляем моба № ' + ReadS( 2 ) ) ;
pck:='' ;
i:= TestPovtor ( TargetID) ;
if i > 0 then
begin
NpcTypeID_List[NpcTypeID_CurrentMob]:= MobsNpcTypeID[i];
SendMsg_to_CL( 'Моб №' + inttostr ( NpcTypeID_CurrentMob) + 'тип: ' +inttostr ( MobsNpcTypeID[i]) +' добавлен в базу' ) ;
log.Lines .Add ( 'Моб №' + inttostr ( NpcTypeID_CurrentMob) + 'тип: ' +inttostr ( MobsNpcTypeID[i]) +' добавлен в базу' ) ;
inc ( NpcTypeID_List_Count) ;
NpcTypeID_CurrentMob:= 0 ;
TargetID:= 0 ;
end ;
end ;
'start' : begin // собственно запуск бота
pck:='' ;
StartGame;
end ;
end ;
if ( not InitMode) then case ( ReadS( 2 ) ) of
'pause' : begin
pck:='' ;
PauseGame;
end ;
'stop' : begin
pck:='' ;
StopGame;
end ;
end ;
end ;
procedure PauseGame;
begin
TimerCombat.enabled := not ( TimerCombat.enabled ) ;
TimerBafBanka.enabled := not ( TimerBafBanka.enabled ) ;
if TimerCombat.enabled then
begin
btnPause.Caption :='Pause' ;
TimerBafBanka.interval := 15000 ;
SendMsg_to_CL( 'Искуственный интелект запущен!' ) ;
log.Lines .Add ( 'Искуственный интелект запущен!' ) ;
end
else
begin
btnPause.Caption :='Repeat' ;
SendMsg_to_CL( 'Искуственный интелект приостановлен.' ) ;
log.Lines .Add ( 'Искуственный интелект приостановлен.' ) ;
end ;
end ;
procedure StartGame;
begin
if ValidateData and InitMode then
begin
CenterFixed:= true ;
SendMsg_to_CL( 'ЗАПУСКАЕМ ИСУСТВЕННЫЙ ИНТЕЛЛЕКТ!' ) ;
log.Lines .Add ( 'ЗАПУСКАЕМ ИСУСТВЕННЫЙ ИНТЕЛЛЕКТ!' ) ;
TargetID:=0 ;
InitMode:= false ;
TimerCombat.enabled :=true ; // запускаем таймер
TimerBafBanka.interval := 15000 ;
TimerBafBanka.enabled := true ;
btnStart.enabled := false ;
btnStop.enabled := true ;
btnPause.enabled := true ;
end
else
begin
SendMsg_to_CL( 'Еще не все параметры заданы. Проверьте параметры...' ) ;
log.Lines .Add ( 'Еще не все параметры заданы. Проверьте параметры...' ) ;
end ;
end ;
procedure StopGame; // остановка кача
begin
TimerCombat.enabled := false ;
InitMode:= true ;
TimerPickUp.enabled :=false ;
TimerBafBanka.enabled :=false ;
TargetID:= 0 ;
ClearDB;
SendMsg_to_CL( 'Искуственный интелект остановлен.' ) ;
log.Lines .Add ( 'Искуственный интелект остановлен.' ) ;
btnStart.enabled := true ;
btnStop.enabled := false ;
btnPause.Caption := 'Pause' ;
btnPause.enabled :=false ;
end ;
function GetMinDistID : integer ; // функция поиска ближайшего моба в БД
var
i, Dist, MinDist : integer ;
begin
result:= 0 ;
if MobsLastIndex = 0 then exit ;
MinDist:=RastoyanieToMe( MobsXYZ[1 ,OX], MobsXYZ[1 ,OY]) ;
for i:=1 to MobsLastIndex do if ( MobsDist[i] <= Radius) and ( MobsIsAttackable[i]) then
begin
Dist:= RastoyanieToMe( MobsXYZ[i,OX], MobsXYZ[i,OY]) ;
if Dist <= MinDist then
begin
Dist:= MinDist;
result:= i;
end ; // если нашли хоть одного моба или несколько, товозращаем индекс ближайшего
end ;
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:=#$1F; //action
WriteD( TargetID) ;
WriteD( MyX) ;
WriteD( MyY) ;
WriteD( MyZ) ;
WriteC( 0 ) ;
SendToServerEx( NickName) ;
end ;
procedure RequestMagicSkillUse ( SkillID: integer ) ; // маг атака
begin
buf:=#$39 ;
WriteD( SkillID) ;
WriteD( 0 ) ;
WriteC( 0 ) ;
SendToServerEx( NickName) ;
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 OnTimerBafBanka ( Sender: TObject ) ; // таймер питья баф-банок
begin
if ( Bottle_1 _Count > 0 ) and ( Bottle_1 _ObjID > 0 ) then
begin
UseItemObjID( Bottle_1 _ObjID) ;
dec ( Bottle_1 _Count) ;
end ;
if ( Bottle_2 _Count > 0 ) and ( Bottle_2 _ObjID > 0 ) then
begin
UseItemObjID( Bottle_2 _ObjID) ;
dec ( Bottle_2 _Count) ;
end ;
TimerBafBanka.interval := Bottle_Interval*60 *1000 ;
end ;
procedure OnTimerPickUp ( Sender: TObject ) ; // таймер поднятия дропа
var
povtor: integer ;
begin
if ( AgroTest > 0 ) then
begin
TargetID:= 0 ;
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, i: integer ;
begin
if TargetID > 0 then // если в прицеле есть моб, то
begin // валим вражину
if ( ( AttackCycle mod 5 ) = 0 ) then
begin
if Spoil and ( not Spoiled) then RequestMagicSkillUse( 254 ) // заспойлим моба если опция включена
else PhisicalAttack;
end ;
inc ( AttackCycle) ;
if AttackCycle > Calculated_AttackTime then // если валим моба больше минуты, значит это баг...
begin
i:= TestPovtor( TargetID) ;
if i > 0 then
begin
MobsIsAttackable[i]:= false ; //DelDBItem(i);
MobsAgression[i]:= false ;
end ;
TargetID:= 0 ;
end ;
exit ;
end ;
Agro:= AgroTest;
if Agro > 0 then // если нас кто-то атакует, то его и выбираем
begin
TargetID:= MobsObjID[Agro];
PhisicalAttack; // берем вражину в таргет
AttackCycle:= 0 ;
exit ;
end ;
if ItemsLastIndex > 0 then // если чего-то валяется на земле, то
begin
InitPickUpMode( true ) ; // надо дроп подбирать
exit ;
end ;
MinDistID:= GetMinDistID; // запускаем алгоритм выбора цели
if MinDistID > 0 then // иначе ищем ближайшего
begin
TargetID:= MobsObjID[MinDistID];
PhisicalAttack; // берем вражину в таргет
AttackCycle:= 0 ;
exit ;
end ;
if ( abs ( MyX-CenterX) > 20 ) and ( abs ( MyY-CenterY) > 20 ) then MoveTo ( CenterX, CenterY, CenterZ) ;
end ;
procedure MoveTo( TargetX,TargetY,TargetZ:integer ) ; //Идти в точку с координатами x,y,z
begin
buf:=#$0F; //01=MoveBackwardToLocation:d(targetX)d(targetY)d(targetZ)d(originX)d(originY)d(originZ)d(moveByMouse)
WriteD( targetx) ; //куда
WriteD( targety) ;
WriteD( targetz) ;
WriteD( MyX) ; //откуда
WriteD( MyY) ;
WriteD( MyZ) ;
WriteD( 1 ) ; //используем 1-мышь 0-клавиатура
SendToServerEx( NickName) ;
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) ;
textMobsLastIndex.text := inttostr ( MobsLastIndex) ;
textMobsKilled.text := inttostr ( MobsKilled) ;
textHPBottleCount.text := inttostr ( HPBottleCount) ;
textBottle_1 _Count.text := inttostr ( Bottle_1 _Count) ;
textBottle_2 _Count.text := inttostr ( Bottle_2 _Count) ;
MobsDBscreen.lines .Clear ;
for i:=1 to MobsLastIndex do // выводим БД мобов
begin
if ( TargetID = MobsObjID[i]) and MobsAgression[i] then
begin
MobsDBscreen.lines .add ( '<> ' +inttostr ( i) +' МобID: ' +inttostr ( MobsObjID[i]) +' ТипID: ' +inttostr ( MobsNpcTypeID[i]) +' дистанция ' +inttostr ( MobsDist[i]) ) ;
continue ;
end ;
if TargetID = MobsObjID[i] then
begin
MobsDBscreen.lines .add ( '-> ' +inttostr ( i) +' МобID: ' +inttostr ( MobsObjID[i]) +' ТипID: ' +inttostr ( MobsNpcTypeID[i]) +' дистанция ' +inttostr ( MobsDist[i]) ) ;
continue ;
end ;
if cbFilterRadius.checked then if MobsDist[i] <= Radius then
begin
MobsDBscreen.lines .add ( '-- ' +inttostr ( i) +' МобID: ' +inttostr ( MobsObjID[i]) +' ТипID: ' +inttostr ( MobsNpcTypeID[i]) +' дистанция ' +inttostr ( MobsDist[i]) ) ;
continue ;
end ;
if MobsAgression[i] then
begin
MobsDBscreen.lines .add ( '<- ' +inttostr ( i) +' МобID: ' +inttostr ( MobsObjID[i]) +' ТипID: ' +inttostr ( MobsNpcTypeID[i]) +' дистанция ' +inttostr ( MobsDist[i]) ) ;
continue ;
end ;
if ( not cbFilterRadius.checked ) then MobsDBscreen.lines .add ( '-- ' +inttostr ( i) +' МобID: ' +inttostr ( MobsObjID[i]) +' ТипID: ' +inttostr ( MobsNpcTypeID[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]) ) ;
if MobsLastIndex = 0 then MobsDBscreen.lines .add ( 'Мобы' ) ;
if ItemsLastIndex= 0 then ItemsDBscreen.lines .add ( 'Дроп' ) ;
end ;
procedure FormClose( Sender: TObject ; var Action: TCloseAction) ;
begin
Action:=caNone;
end ;
procedure CreateLabel ( text : string ) ; // процедура автоматизирует создание текстовых меток в форме
var
l: TLabel;
begin
l:= TLabel.Create ( panel) ;
l.caption :=text ;
l.parent :=panel;
l.left :=10 ;
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 :=80 ;
e.top :=10 +20 *frmParamIndex;
e.width := 95 ;
e.ReadOnly :=true ;
result:= e;
end ;
procedure Free; //Вызывается при выключении скрипта
begin
ClearDB;
TimerForm.free ;
TimerCombat.free ;
TimerPickUp.free ;
TimerBafBanka.free ;
TimerCheckDB.free ;
MobsDBscreen.free ;
ItemsDBscreen.free ;
log.free ;
frm.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) ;
i:=i+48 ;
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 ) *HPLevel) ;
end ;
procedure DrinkBottle; // пьем бутылки и следим за их количеством
begin
if ( HPBottleCount > 0 ) and ( HPBottleObjID > 0 ) then
begin
UseItemObjID( HPBottleObjID) ;
dec ( HPBottleCount) ;
end ;
end ;
procedure MoveToLocation01;
var
i: integer ;
begin
i:= TestPovtor( ReadD( 2 ) ) ;
if i > 0 then updateDB( i, ReadD( 06 ) , ReadD( 10 ) , ReadD( 14 ) , false ) ;
end ;
procedure NpcInfo16;
var
i: integer ;
begin
i:= TestPovtor( ReadD( 2 ) ) ;
if i = 0 then AddtoDB ( ReadD( 2 ) , ReadD( 6 ) , ReadD( 14 ) , ReadD( 18 ) , ReadD( 22 ) , InMobsList( ReadD( 6 ) ) )
else UpdateDB( i, ReadD( 14 ) , ReadD( 18 ) , ReadD( 22 ) , false ) ;
end ;
procedure Attack05;
var
i: integer ;
begin
i:= TestPovtor( ReadD( 2 ) ) ;
if i = 0 then log.Lines .Add ( 'Глюк, моб не найден, или нас утакует другой игрок!!!' )
else UpdateDB( i, ReadD( 15 ) , ReadD( 19 ) , ReadD( 23 ) , true ) ;
end ;
procedure Die06;
var
i: integer ;
begin
i:= TestPovtor( ReadD( 2 ) ) ;
if i > 0 then
if MobsObjID[i] = TargetID then
begin
TimerCombat.enabled := false ;
if Spoil and Spoiled then
if ReadD( 22 ) = 1 then RequestMagicSkillUse( 42 ) ;
LastKilledMobObjID:=TargetID;
inc ( MobsKilled) ; // подводим статистику
MobsIsAttackable[i]:= false ;
MobsAgression[i]:= false ;
Spoiled:= false ;
TargetID:= 0 ;
TimerCombat.enabled := true ;
end ;
end ;
procedure DeleteObject12;
var
i: integer ;
begin
if LastKilledMobObjID = ReadD( 2 ) then
begin
LastKilledMobObjID:= 0 ;
i:= TestPovtor( ReadD( 2 ) ) ;
if i > 0 then DelDBItem( i) ;
exit ;
end ;
i:= CheckItems( ReadD( 2 ) ) ;
if i > 0 then
begin
if Items_ObjectID[i] = TargetID then TargetID:= 0 ;
DelDroppedItem( i) ;
exit ;
end ;
i:= TestPovtor( ReadD( 2 ) ) ;
if i > 0 then
begin
if TargetID = ReadD( 2 ) then TargetID:= 0 ;
DelDBItem( i) ;
exit ;
end ;
end ;
begin
if pck = '' then exit ;
if ( ConnectName = NickName) and FromServer then // разбор пакетов от сервера
case pck[1 ] of
#$01 : MoveToLocation01; // MoveToLocation:h(ObjectID)d(CurX)d(CurY)d(CurZ)d(DestX)d(DestY)d(DestZ)
// #$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;
btnInit.enabled := false ;
if MyHP = 0 then // Проверка не убили ли нас...
begin
SendMsg_to_CL( 'Нас убили...' ) ;
log.Lines .Add ( 'Нас убили...' ) ;
StopGame;
end ;
end ;
#$05 : if ( ReadD( 6 ) = MyID) and ( not InitMode) then Attack05; // 05= Attack:d(AttackerID)d(TargetID)d(Damage)b(Flags)d(X)d(Y)d(Z)h(Hits)
#$48 : begin ; // 48= MagicSkillUse:h(CharID)h(targetID)d(skillID)d(skillLvl)d(hitTime)d(reuseDelay)d(X)d(Y)d(Z)w(count)d(d)d(d)d(d)
if ( ReadD( 2 ) = MyID) and ( ReadD ( 6 ) = TargetID) and ( ReadD( 10 ) = 254 ) then Spoiled:= true ;
end ;
#$06 : Die06; // Die:d(ChaID)
#$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_to_CL( 'Нас убили...' ) ;
log.Lines .Add ( 'Нас убили...' ) ;
StopGame;
end ;
end ;
#$12 : DeleteObject12; // DeleteObject:h(ObjectID)
#$16 : if ( ReadD( 10 ) =1 ) and ( pck[121 ]=#$00 ) then NpcInfo16; // 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; // Инвентарь
if HPBottleID <> 0 then
begin
HPBottleObjID:= getinv( HPBottleID, 2 ,1 ) ;
HPBottleCount:= getinv( HPBottleID, 2 ,3 ) ;
end ;
if Bottle_1 _ID <> 0 then
begin
Bottle_1 _ObjID:=getinv( Bottle_1 _ID, 2 ,1 ) ;
Bottle_1 _Count:=getinv( Bottle_1 _ID, 2 ,3 ) ;
end ;
if Bottle_2 _ID <> 0 then
begin
Bottle_2 _ObjID:=getinv( Bottle_2 _ID, 2 ,1 ) ;
Bottle_2 _Count:=getinv( Bottle_2 _ID, 2 ,3 ) ;
end ;
end ;
#$27 : begin
InventoryUpdate;
if HPBottleID <> 0 then
begin
HPBottleObjID:= getinv( HPBottleID, 2 ,1 ) ;
HPBottleCount:= getinv( HPBottleID, 2 ,3 ) ;
end ;
if Bottle_1 _ID <> 0 then
begin
Bottle_1 _ObjID:=getinv( Bottle_1 _ID, 2 ,1 ) ;
Bottle_1 _Count:=getinv( Bottle_1 _ID, 2 ,3 ) ;
end ;
if Bottle_2 _ID <> 0 then
begin
Bottle_2 _ObjID:=getinv( Bottle_2 _ID, 2 ,1 ) ;
Bottle_2 _Count:=getinv( Bottle_2 _ID, 2 ,3 ) ;
end ;
end ;
#$13 : if RestartMode then // CharacterSelectionInfo
begin
buf:=#$12 ; // CharacterSelected
WriteD( CharNumber) ;
buf:= buf + hstr( '00 00 00 00 00 00 00 00 00 00 00 00 00 00' ) ;
SendToServerEx( NickName) ;
RestartMode:= false ;
end ;
end ;
if ( ConnectName = NickName) and FromClient then // разбор пакетов от клиента
case pck[1 ] of
#$1F: if InitMode then TargetID:= ReadD( 2 ) ; // Action:h(ObjectID)d(OriginX)d(OriginY)d(OriginZ)b(ActionID)
#$49 : UserCommands; // Say2:s(Text)d(Type)s(Target)
#$59 : begin // ValidatePosition:d(X)d(Y)d(Z)d(Heading)d(Data)
MyX:= ReadD( 2 ) ;
MyY:= ReadD( 6 ) ;
MyZ:= ReadD( 10 ) ;
if ( not CenterFixed) and InitMode then
begin
CenterX:= MyX;
CenterY:= MyY;
CenterZ:= MyZ;
end ;
end ;
end ;
end .
запустил, ввожу какую либо команду выбивает с дисконектом ла2.. хотя в логе чата команду принял...
17.04.2009, 02:38
#35
Новичок
Регистрация: 17.04.2009
Сообщений: 3
Сказал Спасибо: 0
Имеет 0 спасибок в 0 сообщенях
хелп,дорогие отцы!
юзаю(точнее пытаюсь) для абиса ПХ 3.4.1,хочу квест итемы сделать как будто я их через магазин купил,покупаю шмотку,код соответствует расшифровке покупки,копирую в окно посылки,а в окне посылки уже этот код имеет другое ID(или вообще никакого) соответствующее ID пакета от сервера,а не от клиента,в чем может быть дело и как исправить?
PS может кто скинет готовый пакет на покупку через магаз?
17.04.2009, 13:05
#36
Рыцарь
Регистрация: 07.03.2009
Сообщений: 9,139
Сказал Спасибо: 70
Имеет 2,820 спасибок в 1,735 сообщенях
юзай
l2phx.3.5.4.105.rar
это раз.
не забывай выбирать направление отправки, это 2.
ах. да. и внимательно читаем этот топик, особенно место по поводу несоответствия протоколов для разных направлений.
__________________
L2Ext - project closed.
Последний раз редактировалось alexteam, 17.04.2009 в 13:39 .
17.04.2009, 13:39
#37
Новичок
Регистрация: 17.04.2009
Сообщений: 17
Сказал Спасибо: 2
Имеет 2 спасибок в 2 сообщенях
из того что я понял то в L2ph надо везде ставить галочки на Gracia где есть) но в пакетах ID править от тех что были от Интерлюди, правильно я понял?)
Последний раз редактировалось pickwick, 17.04.2009 в 13:58 .
17.04.2009, 15:49
#38
Новичок
Регистрация: 17.04.2009
Сообщений: 3
Сказал Спасибо: 0
Имеет 0 спасибок в 0 сообщенях
скачал новую версию,он у меня теперь вообще не коннектит,клиент заходит,а ПХ молчит
17.04.2009, 16:15
#39
Рыцарь
Регистрация: 07.03.2009
Сообщений: 9,139
Сказал Спасибо: 70
Имеет 2,820 спасибок в 1,735 сообщенях
для особо одаренных при первом запуске пх выдает сообщение о том что его необходимо настроить.
Добавлено через 1 минуту
видно надо добавить функцию для особоособоособо одаренных которая будет зафлуживать этими сообщениями весь экран.
Добавлено через 19 минут
а потом взрывать системник нафих.
Добавлено через 30 секунд
чтото я сегодня.. злой какойто -(
__________________
L2Ext - project closed.
Последний раз редактировалось alexteam, 17.04.2009 в 16:15 .
Причина: Добавлено сообщение
17.04.2009, 21:37
#40
Рыцарь
Регистрация: 28.09.2007
Сообщений: 1,558
Сказал Спасибо: 71
Имеет 351 спасибок в 244 сообщенях
alexteam , надо тогда так,сначала на весь экран вопрос: ВЫ ОСОБО ОДАРЕННЫЙ???? и кнопки "да" и "нет", если нет - то тогда все норм, при след запуске уже не появляется, а если да - то твой вариант =)
Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
Часовой пояс GMT +4, время: 03:16 .
vBulletin style designed by
MSC Team .
Powered by vBulletin® Version 3.6.11
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод:
zCarot
Вы хотите чувствовать себя в безопасности? чоп Белган обеспечит её!