Рейтинг темы:
  • 0 Голос(ов) - 0 в среднем
  • 1
  • 2
  • 3
  • 4
  • 5
NpcWalkerAI
#1
Доброй ночи. Ув. форумчане, знатоки и начинающие - помогите разобраться с АИ нпц волкеров. Хочу сделать так, что бы этот нпц мог умереть как и простые нпц. но в АИ у него это не было заранее предусмотрено, начал копать соседние классы (CharacterAI, SiegeGuardAI), нашел пару методов, долго мучался, но так ничего и не получилось, вот код всего класса:

Код:
public class L2NpcWalkerAI extends L2CharacterAI implements Runnable
{
private static final int DEFAULT_MOVE_DELAY = 0;
private long _nextMoveTime;

/** The L2Attackable AI task executed every 1s (call onEvtThink method) */
private Future<?> _aiTask;

private boolean _walkingToNextPoint = false;
/**
  * home points for xyz
  */
int _homeX, _homeY, _homeZ;

/**
  * route of the current npc
  */
private final FastList<L2NpcWalkerNode> _route = NpcWalkerRoutesTable.getInstance().getRouteForNpc(getActor().getNpcId());
/**
  * current node
  */
private int _currentPos;

/**
  * Constructor of L2CharacterAI.<BR>
  * <BR>
  *
  * @param accessor The AI accessor of the L2Character
  */
public L2NpcWalkerAI(L2Character.AIAccessor accessor)
{
  super(accessor);
  // Do we really need 2 minutes delay before start?
  // no we dont... :)
  ThreadPoolManager.getInstance().scheduleAiAtFixedRate(this, 0, 1000);
}
@Override
public void run()
{
  onEvtThink();
}

@Override
protected void onEvtThink()
{
  if(!Config.ALLOW_NPC_WALKERS)
   return;
  if(isWalkingToNextPoint())
  {
   checkArrived();
   return;
  }

  if(_nextMoveTime < System.currentTimeMillis())
  {
   walkToLocation();
  }
}
/**
  * If npc can't walk to it's target then just teleport to next point
  *
  * @param blocked_at_pos ignoring it
  */
@Override
protected void onEvtArrivedBlocked(L2CharPosition blocked_at_pos)
{
  _log.warning("NpcWalker ID: " + getActor().getNpcId() + ": Blocked at rote position [" + _currentPos + "], coords: " + blocked_at_pos.x + ", " + blocked_at_pos.y + ", " + blocked_at_pos.z + ". Teleporting to next point");

  if(_route.size()<=_currentPos)
   return;

  int destinationX = _route.get(_currentPos).getMoveX();
  int destinationY = _route.get(_currentPos).getMoveY();
  int destinationZ = _route.get(_currentPos).getMoveZ();
  getActor().teleToLocation(destinationX, destinationY, destinationZ, false);
  super.onEvtArrivedBlocked(blocked_at_pos);
}

private void checkArrived()
{
  if(_route.size()<=_currentPos)
   return;

  int destinationX = _route.get(_currentPos).getMoveX();
  int destinationY = _route.get(_currentPos).getMoveY();
  int destinationZ = _route.get(_currentPos).getMoveZ();
  if(getActor().getX() == destinationX && getActor().getY() == destinationY && getActor().getZ() == destinationZ)
  {
   String chat = _route.get(_currentPos).getChatText();

   if(chat != null && !chat.equals("NULL"))
   {
    try
    {
     getActor().broadcastChat(chat);
    }
    catch(ArrayIndexOutOfBoundsException e)
    {
     if(Config.ENABLE_ALL_EXCEPTIONS)
      e.printStackTrace();
    
     _log.info("L2NpcWalkerInstance: Error, " + e);
    }
   }
   chat = null;
   //time in millis
   long delay = _route.get(_currentPos).getDelay() * 1000;

   //sleeps between each move
   if(delay < 0)
   {
    delay = DEFAULT_MOVE_DELAY;
    if(Config.DEVELOPER)
    {
     _log.warning("Wrong Delay Set in Npc Walker Functions = " + delay + " secs, using default delay: " + DEFAULT_MOVE_DELAY + " secs instead.");
    }
   }
   _nextMoveTime = System.currentTimeMillis() + delay;
   setWalkingToNextPoint(false);
  }
}

private void walkToLocation()
{
  if(_currentPos < _route.size() - 1)
  {
   _currentPos++;
  }
  else
  {
   _currentPos = 0;
  }
  if(_route.size()<=_currentPos)
   return;

  boolean moveType = _route.get(_currentPos).getRunning();

  /**
   * false - walking true - Running
   */
  if(moveType)
  {
   getActor().setRunning();
  }
  else
  {
   getActor().setWalking();
  }
  //now we define destination
  int destinationX = _route.get(_currentPos).getMoveX();
  int destinationY = _route.get(_currentPos).getMoveY();
  int destinationZ = _route.get(_currentPos).getMoveZ();

  //notify AI of MOVE_TO
  setWalkingToNextPoint(true);
  setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new L2CharPosition(destinationX, destinationY, destinationZ, 0));
}

@Override
public L2NpcWalkerInstance getActor()
{
  return (L2NpcWalkerInstance) super.getActor();
}
public int getHomeX()
{
  return _homeX;
}

public int getHomeY()
{
  return _homeY;
}
public int getHomeZ()
{
  return _homeZ;
}

public void setHomeX(int homeX)
{
  _homeX = homeX;
}
public void setHomeY(int homeY)
{
  _homeY = homeY;
}

public void setHomeZ(int homeZ)
{
  _homeZ = homeZ;
}
public boolean isWalkingToNextPoint()
{
  return _walkingToNextPoint;
}

public void setWalkingToNextPoint(boolean value)
{
  _walkingToNextPoint = value;
}

@Override
protected void onEvtDead()
{
  stopAITask();
  stopFollow();
  // Kill the actor client side by sending Server->Client packet AutoAttackStop, StopMove/StopRotation, Die (broadcast)
  clientNotifyDead();
  super.onEvtDead();

}
public void stopAITask()
{
  if(_aiTask != null)
  {
   _aiTask.cancel(false);
   _aiTask = null;
  }
  _accessor.detachAI();
}
/*public boolean isAutoAttackable(L2Character attacker)
{
  if(attacker instanceof L2PcInstance)
  {
   return false;
  }
}*/
}

нашел единственное что хоть как-то могло бы быть подобным - StopAITask. но немного не понимаю как он работает. и все-равно нпц не умирает(

подскажите плз, что делать!?
[Изображение: ck.gif]
Ответ
#2
mego4el Написал:Доброй ночи. Ув. форумчане, знатоки и начинающие - помогите разобраться с АИ нпц волкеров. Хочу сделать так, что бы этот нпц мог умереть как и простые нпц. но в АИ у него это не было заранее предусмотрено, начал копать соседние классы (CharacterAI, SiegeGuardAI), нашел пару методов, долго мучался, но так ничего и не получилось, вот код всего класса:

код
нашел единственное что хоть как-то могло бы быть подобным - StopAITask. но немного не понимаю как он работает. и все-равно нпц не умирает(

подскажите плз, что делать!?

Не совсем понял суть проблемы.
суть волкера, это только манипуляция нпс.
А сам нпс он настраивается в npc.
Или ты хочешь чтобы он доходил до определённой точки и умирал?
Ответ
#3
нет. он бегает, и бегает не только в городах ( в моем случае).
я написал проверку, что бы нельзя было бить волкеров в городе. хочу сделать теперь, что бы за городом их можно было УБИВАТЬ.

бить то их можно. но у них бесконечное хп. и я не понимаю как сделать, что бы они умирали.(
[Изображение: ck.gif]
Ответ
#4
у вас все нпц бессмертны ибо это включено в настройках.
Ответ
#5
mego4el;171939 Написал:нет. он бегает, и бегает не только в городах ( в моем случае).
я написал проверку, что бы нельзя было бить волкеров в городе. хочу сделать теперь, что бы за городом их можно было УБИВАТЬ.

бить то их можно. но у них бесконечное хп. и я не понимаю как сделать, что бы они умирали.(
Я конечно хз как там у СФ, но на ребоподобных - метод который снимает ХП по условиям. Там проверку на тип АИ и в путь Wink
Ответ
#6
Цитата:Я конечно хз как там у СФ, но на ребоподобных - метод который снимает ХП по условиям. Там проверку на тип АИ и в путь
я совсем ничего не понял из того, что вы сказали :dc:
[Изображение: ck.gif]
Ответ
#7
можно обойтись и без ява: делаешь прямоугольную зону на всех выходах из города,добоавляешь эффект к этой зоне-скил,например,как Golden Spice(Beast Farm).Бот,прошедший через эту зону будет изменён на другой тип бота(из L2Walker в L2Guard или L2Monster-в тех,кого можно убить) Где то в исходниках видел,что нужно только ID добавить(из кого и в кого)
Ответ
#8
Поменяй тип нпц на L2Monster.
Ответ


Перейти к форуму:


Пользователи, просматривающие эту тему: 1 Гость(ей)