Glassman Posted October 17, 2023 Report Share Posted October 17, 2023 Скрипт отходит на время рестарта в безопасную зону и после рестарта возвращается на спот. Так же следит за мп у критически важных персов (хилы, заливки, маги). Если мп мало (<20% у всех), то идет нв безопасную зону, где ждет регена. Пока стоит в безопасной зоне - отбивается от агро-мобов, которые повисли на пати. Поддерживает офф-пати сапорт. Как в случае защиты от агро-мобов на ресте, так и при контроле мп. Скрипт должен запускаться на персе, по которому настроен ассист и фоллоу. Настройка скрипта под себя: 1. Время рестарта. Задать в константе str_restart_time время, когда отходить на отдых перед рестартом с учетом своего часового пояса. 2. Запуск после рестарта. Задать в константа str_start_time время, когда возвращаться на спот после рестарта с учетом своего часового пояса. 3. Офф-пати персы. В массиве off_party_chars указать перечень персов, которые у вас вне пати. Если таких нет, то оставить массив пустым (const off_party_chars: array of string = [];) 4. Критически важные персонажи, у которых мониторить уровень мп. Указать в массиве mp_critical список таких персонажей. 5. Пусть на место отдыха. В процедуре MoveToSafeSpot() записать свои команды передвижения со спота в зону отдыха. 6. Возврат на спот. В процедуре MoveFromSafeSpot() записать свои команды возврата на спот из зоны отдыха. P.S. В примере скрипта зона кача - круглая комната перед первым мостом в ЛОА. Отдых - в кишке наверх к хавлерам. P.P.S. Процедура убивания агро-мобов плохо работает с магическими атаками мобов. Пока моб не подойдет и руками не стукнет свою цель, его не будут убивать. Особых проблем это не создает, но стоит иметь в виду. uses SysUtils; const str_restart_time: string = '16:55:00'; const str_start_time: string = '17:15:00'; const off_party_chars: array of string = ['OffPartyEE', 'OffPartySE']; const mp_critical: array of string = ['OffPartyEE', 'OffPartySE', 'EE', 'Mage1', 'Mage2', 'Mage3']; var ct, restart_time, start_time: tDateTime; is_restarting, is_resting: boolean; cntr: TL2Control; normal_mana, i: integer; //route from safe spot to combat zone procedure MoveFromSafeSpot(); begin Engine.MoveTo(147080, 119400, -4304); Engine.MoveTo(147048, 119944, -4464); Engine.MoveTo(147240, 120536, -4640); Engine.MoveTo(147656, 121240, -4792); end; //route from combat zone to safe spot procedure MoveToSafeSpot(); begin Engine.MoveTo(147624, 121240, -4792); Engine.MoveTo(147304, 120904, -4704); Engine.MoveTo(147032, 120248, -4536); Engine.MoveTo(147000, 119608, -4368); Engine.MoveTo(147016, 119224, -4248); end; //true if time d1 > d2 function compare_time(d1: TDateTime; d2: TDateTime): boolean; var hour, minute, second, ms: word; c1, c2: tDateTime; begin decodetime(d1, hour, minute, second, ms); c1 := encodeTime(hour, minute, second, ms); decodetime(d2, hour, minute, second, ms); c2 := encodeTime(hour, minute, second, ms); result := (c1 - c2) > 0; end; procedure Kill(Enemy: TL2Live); begin if Enemy.dead then exit; Engine.SetTarget(Enemy); delay(300); while not Enemy.dead do begin //Engine.Attack(); delay(500); end; end; function IsAgr(E:TL2Control; Mob: TL2Npc): boolean; begin result := (Mob.AtkOID = E.GetUser().OID) and (not Mob.Dead); end; function AttackedBy(E:TL2Control): TL2Npc; var moblist: TNpcList; cnt: integer; begin result := nil; moblist := E.GetNpcList(); for cnt:= 0 to moblist.Count-1 do begin if IsAgr(E, moblist(cnt)) then begin result:= moblist(cnt); break; end; end; end; procedure BeatOff(); var Enemy: TL2Live; i: integer; E: TL2Control; HaveMobsOnParty: boolean; begin HaveMobsOnParty := true; while HaveMobsOnParty do begin HaveMobsOnParty := false; Enemy := AttackedBy(Engine); if (Enemy <> nil) then begin Kill(Enemy); HaveMobsOnParty := true; end; for i := 0 to Engine.GetParty().chars.count - 1 do begin E := GetControl(Engine.GetParty().chars.items(i).name); if Assigned(E) and (E.status = lsOnline) then begin Enemy := AttackedBy(E); if (Enemy <> nil) then begin Kill(Enemy); HaveMobsOnParty := true; end; end; end; for i := 0 to Length(off_party_chars) - 1 do begin E := GetControl(off_party_chars[i]); if Assigned(E) and (E.status = lsOnline) then begin Enemy := AttackedBy(E); if (Enemy <> nil) then begin Kill(Enemy); HaveMobsOnParty := true; end; end; end; delay(500); end; end; begin restart_time := strtotime(str_restart_time); start_time := strtotime(str_start_time); is_restarting:= false; is_resting := false; while true do begin ct := Now; if is_restarting and (engine.status = lsOnline) then begin if compare_time(ct, start_time) then begin is_restarting := false; MoveFromSafeSpot(); Engine.FaceControl(0, true); end; if not compare_time(ct, start_time) then begin BeatOff(); end; end; if not is_restarting then begin if compare_time(ct, restart_time) and not compare_time(ct, start_time) and (engine.status = lsOnline) then begin is_restarting := true; Engine.FaceControl(0, false); MoveToSafeSpot(); end; end; if not is_resting and (Length(mp_critical) > 0) then begin normal_mana := Length(mp_critical); for i := 0 to Length(mp_critical) - 1 do begin cntr := GetControl(mp_critical[i]); if Assigned(cntr) and (cntr.status = lsOnline) then begin if (cntr.GetUser().MP < 20) then normal_mana := normal_mana - 1; end; end; if (normal_mana = 0) then begin Engine.EnterText('#mp low. resting.'); is_resting := true; Engine.FaceControl(0, false); MoveToSafeSpot(); end; end; if is_resting and (Length(mp_critical) > 0) and not is_restarting then begin BeatOff(); normal_mana := 0; for i := 0 to Length(mp_critical) - 1 do begin cntr := GetControl(mp_critical[i]); if Assigned(cntr) and (cntr.status = lsOnline) then begin if (cntr.GetUser().MP > 80) then normal_mana := normal_mana + 1; end; end; if (normal_mana = Length(mp_critical)) then begin is_resting := false; MoveFromSafeSpot(); Engine.FaceControl(0, true); end; end; delay(1000); end; end. 1 1 Link to comment Share on other sites More sharing options...
nixer Posted October 17, 2023 Report Share Posted October 17, 2023 За труд лайк =) Есть такой еще скрипт https://adrenalinebot.com/ru/api/example/stop-farming-on-detecting-strangers-and-retreat-to-a-secluded-place. Там используют немного другую функцию на проверку агро: function IsAgr(Mob: TL2Npc): boolean; begin result:= (Mob.Target = User) and (not Mob.Dead); end; > Пока моб не подойдет и руками не стукнет свою цель, его не будут убивать Возможно решает эту проблему, т.к. просто использует таргет вместо детектора атаки (но я не проверял) . Вместо User подставить контроллер бота. Я сам планирую написать похожий скрипт, как пример будет полезно, но я наверное буду делать на основе примера из адрика + на платном боте (с нормальным поиском путей). Оффтоп: Есть еще у меня скрипт на автологин + детектор оффлайна (обычный метод не всегда работает) + простейший парсер текстовика с логинами и паролями, вроде работает пока +- нормально (пока тестирую его). Может выложу как доделаю. Link to comment Share on other sites More sharing options...
Glassman Posted October 18, 2023 Author Report Share Posted October 18, 2023 Проблема в том, что на этом сервере ты не можешь взять ассист с моба и его Mob.Target всегда пустой. Поэтому через айдишники сделано. Link to comment Share on other sites More sharing options...
nixer Posted October 18, 2023 Report Share Posted October 18, 2023 (edited) Понятно, кстати я проверил на обычных мобах Wyrm в Dragon Valey, как только он кастует blaze, OID совпадает с моим, когда начинает бежать на меня не совпадает, когда бьет совпадает. Тестил вот так: while true do begin print(User.Target.name); print(User.Target.Cast.name); print(User.Target.AtkOID = User.OID); engine.delay(1000); end; Атакует, не разу не бил [3:53:22 PM] Wyrm [3:53:22 PM] Blaze [3:53:22 PM] true Бежит на нас [3:53:23 PM] Wyrm [3:53:23 PM] Blessed Spiritshot (No-grade) [3:53:23 PM] false [3:53:24 PM] Wyrm [3:53:24 PM] Blessed Spiritshot (No-grade) [3:53:24 PM] false [3:53:25 PM] Wyrm [3:53:25 PM] Blessed Spiritshot (No-grade) [3:53:25 PM] false [3:53:26 PM] Wyrm [3:53:26 PM] Blessed Spiritshot (No-grade) [3:53:26 PM] false Добежал и ударил [3:53:27 PM] Wyrm [3:53:27 PM] Blessed Spiritshot (No-grade) [3:53:27 PM] true Получается OID сбивается во время того как он бежит. Возможно проблему можно решить, просто записывать в массив (допустим 100 элементов) OID мобов которые кастанули что-то на нас хотя-бы раз (если нет проблем с OID и он почти всегда уникальный) и сбрасывать его как только он заполнился или по таймеру. Ну соответственно включить проверку массива в IsAgr. Edited October 18, 2023 by nixer Link to comment Share on other sites More sharing options...
Glassman Posted October 18, 2023 Author Report Share Posted October 18, 2023 Можно и так, да. Обычно мобы не кастуют больше 2-3 кастов. Бегут рукой бить. ))) так что обычно все ок работает и так. Ни разу не видел, чтоб пати упала. Если даже 1-2 нюка пропускают, то биш отхилит. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now