Форум работает в тестовом режиме. Все данные были перенесены со старого сайта 2018 года. Некоторая информация может быть недоступна, например вложения или хайды. Просьба сообщать о данных случаях через функционал "Жалоба", прямо под постом, где отсуствуют данные из хайда или проблемы с вложением.
Могут быть проблемы в "выкидыванием" с форума (слетевшей авторизацией). Нужно собрать статистику таких случаев.
Есть Тема, куда можете сообщить о проблемах с сайтом либо просто передать привет.

Getfacestate , условие на мобов , включен ли интерфейс и мертва ли цель

Рег
28 Ноя 2015
Сообщения
126
Реакции
0
Добрый день.
Для примера кусок кода - в идеале должен прибегать фармить до нужного лвл, после получения лвла должна работать проверка: бьет ли его моб, если моб бьет и он живой, а интерфейс выключен , то добивает моба и улетает.
Будет ли работать проверка? или как-то неверно построил код
Код:
Uses SysUtils, Classes;
var  Item: TL2Item; Npc: TL2Npc; obj: TL2NPC; L2Skill: TL2Skill;
function mobsAttacking : Boolean;
var i, n: Integer; 
begin
   n := 0;
   for i := 0 to NpcList.Count - 1 do
      if (NpcList.Items(i).Target = User) and not NpcList.Items(i).Dead then inc(n);

   Result := n > 0;
end;
begin
Engine.MoveTo(-115731, 247010, -3278);
if User.InRange(-115731, 247010, -3278,500,500) then
Engine.LoadZone('farmdo15');
Engine.loadconfig('HumanWiz');
while User.Level<15 do begin
 Engine.Facecontrol(0,True); 
if (user.level= 15) then 
Engine.Facecontrol(0,False);
end;
begin
if mobsattacking and engine.getfacestate(0)=true and not (user.target.dead) then
delay(300);
Engine.AutoSoulshot(5790,true); //Автоюз маг сосок ид5790, файтер соски5789 
 Engine.UseSkill(1177);
end;
engine.clearzone;
Delay(1000);
Engine.UseKey('f12');
Print('получили 10 лвл');
end.
 
тип переменной должен быть TL2Live, а не TL2Npc. не видел чтобы конструкция проверки таргета у мобов работала на фришках, так что это нужно проверять отдельно, если такая конструкция не будет работать придется как-то извращаться - сое или смерть + продолжение скрипта.

if mobsattacking and engine.getfacestate(0)=true and not (user.target.dead) then
как условие это будет работать? если mobsattacking передает кол-во атакуемых мобов, а не true/false, что нужно для if. тогда нужно ставить условие аля if(mobsattacking>0). скорее всего нужно для if будет добавить скобки для условий, сое лучше юзать через useitem, а не с панели. ну и нужно делать табуляцию, чтобы быстрее разбираться в коде и видеть все ли begin .. end закрыты.
 
Про переменную понял. А это условие будет работать?

if User.InCombat = false then break;

Только я так и не разобрался как его использовать, т.к. не понимаю как грамотно вставить это условие в код. Сразу отключает интерфейс и чар улетает) Что значит делать табуляцию?
 
CMAK написал(а):
Про переменную понял. А это условие будет работать?
про break точно не помню, надо почитать лучше, вроде как брик выходит из цикла и такой метод особо не подходит, так как может завершить скрипт (?).

лучше использовать что-то вроде while(user.incombat)

procedure CheckAttackingMobs;
begin
//print('Проверяем, аттакуют ли нас мобы');
while user.incombat do
begin
if(user.target.incombat) then engine.attack(1000);
if(user.target.dead) then engine.canceltarget;
delay(100);
end;
//print('Мобы не атакуют:)');
end;
я как-то использовал такой костыль, перед ним отключался интерфейс, так как по механике игры если моб нас атакует то возьмет в таргет, таким образом после убийства прицепившихся мобов таргет снимается и берется автоматом на моба, который бьет нас, после того как чар будет не в "стойке" можно продолжать скрипт.

procedure lvl1_6;
begin
print('1-6 лвл');
print('Телепорт Talking Island Village -> Obelisk of Victory');
while not user.inrange(-99586, 237637, -3552, 250, 1000) do
begin
engine.bypasstoserver('_bbshome');
delay(d);
engine.bypasstoserver('_bbsteleport');
delay(d);
engine.bypasstoserver('_bbsteleport:page teleport_location');
delay(d);
engine.bypasstoserver('_bbsteleport:page teleport_villages_locations_human');
delay(d);
engine.bypasstoserver('_bbsteleport:go -99586 237637 -3568');
delay(d_tp);
end;

exp_until(6);
end;
Код:
procedure exp_until(level:integer);
begin
  print('Начинаем фармить мобов');
  while user.level<level do
  begin
    if(user.dead) then
    begin
      engine.FaceControl(0,false);
      engine.gohome(rtTown);
      break;
    end;
    engine.FaceControl(0,true);
    delay(d);  
  end;

  engine.FaceControl(0,false);
  print('Заканчиваем фармить мобов');

  CheckAttackingMobs;
end;
если код много раз повторяется, как в моем примере запуска на споте на фарм до n уровня то лучше реализовать все через процедуры, для дальнейшей простой модификации кода через процедуры.

грубо говоря табуляция это когда в коде есть отступы, в каждом вложенном for, while, if, etc.
Код:
procedure autoFollow(nickName: string = '');
var
  followActor: TL2Live;
begin
  while Engine.Status = lsOnline do
  begin
  delay(50);

  if isCasting(User) or (Party.Chars.Count = 0) or not turnOn then
    continue;

  if (Length(nickName) = 0) or not Party.Chars.ByName(nickName, followActor) then
    followActor := Party.leader;
    
  if (User.DistTo(followActor) > 300) and (User.DistTo(followActor) < 3000)
    {and (partyCount(pClarityF, true) = 0)
    and (partyCount(pMentalF, true) = 0)
    //and (partyCount(pResistShockF, true) = 0)
    and (partyCount(pWildMagicF, true) = 0)
    and (partyCount(pSpiritF, true) = 0)
    and (partyCount(pConcentrationF, true) = 0)  }
    and not isStunned(User) and not isRooted(User) and not isAffraid(User)
    then
      Engine.MoveTo(followActor, -200);  
 
  end;
end;
Код:
procedure moveToLocWithCheck(coordHolder: DimensionArray; mobsCheckRange: integer = 200; mobsCountToAttack: integer = 4);
var                                                                 
  i: integer;
  _index: integer;
begin
  _index := 0;
  _index := getClosestLoc(coordHolder);
  try
  if (inRange(User, isleX, isleY, isleZ, isleRange)) then
    begin
      delay(1000);
      if (Length(coordHolder) > 0) then
      begin
        for i:=_index to Length(coordHolder)-1 do
        begin
          if not canMoveTo(coordHolder[i, 0], coordHolder[i, 1]) then
          begin
            continue;
            print('Tyrannosaur on my way..');
          end;
          Engine.MoveTo(coordHolder[i, 0], coordHolder[i, 1], coordHolder[i, 2]);

          if (countNpcs(400) > 5) then
            delay(2000)
          else
            delay(300);
            
          if (countNpcs(120) > mobsCountToAttack) then
            attackMobs;
            
        end;  
      end;
    end
    else
      print('Oh, I am not on isle');
  except
    print('Exception in back function');
  end;    
end;
 
@SoundShocking, по красоте расписал.
Когда заканчивает бить моба, стоит пока не выйдет из боя и потом начинает юзать сое, ну а если мобы нападают то соответственно бьет их винд страйком)
Спасибо за помощь!
Код:
Uses SysUtils, Classes;

var Item: TL2Item; Npc: TL2Npc; obj: TL2NPC; L2Skill: TL2Skill;

procedure CheckAttackingMobs;
begin
//print('Проверяем, аттакуют ли нас мобы');
  while user.incombat do
  begin
    if(user.target.incombat) then
    Engine.AutoSoulshot(5790,true);
    Engine.UseSkill(1177);
      if(user.target.dead) then engine.canceltarget;
      delay(100);
      end;
      //print('Мобы не атакуют:)');
      end;

procedure ExpTo15;
begin
Engine.MoveTo(-114718, 245985, -3263);
 if User.InRange(-114718, 245985, -3263,100,100) then
 Engine.LoadZone('farmdo15');
 Engine.loadconfig('HumanWiz');
  while User.Level<20 do begin
  Engine.Facecontrol(0,True);
  end;
    if (user.level= 20) then begin
    Engine.Facecontrol(0,False);   
    CheckAttackingMobs;
    print('закончили 20лвл');
    delay(100);
    engine.clearzone;
    Engine.UseItem(10650);
    end;
    end;
 begin //start of main body
 Script.NewThread(@expto15); 
 end. //end of main body
 
function GetCountMyAttackerNpc:integer;
var
idx:integer;
begin
result:=0;
for idx:=0 to NpcList.Count-1 do begin
if Not(NpcList.Items(idx).Dead)and(NpcList.Items(idx).AtkOID=User.Oid)then begin
inc(result);
end;
end;
end;


вернулся 0 - не атакуют.

А свойство InCombat - это не "меня атакуют", а - "я в состоянии боя". Т.е. атакующих может уже и не быть, просто персонаж еще не вышел из "боевого режима", или находится под каким-либо дот-дебафом, или стоит в "опасной" зоне, типа лавы.
 
Спасибо, ну да твой вариант вернее конечно, но и предыдущий впринципе работает.
А как написать условие для этой функции?
 
вместо
while user.incombat do
поставить
while GetCountMyAttackerNpc<>0 do
 
Назад
Сверху