Перейти к содержанию
Авторизация  
BrainEater

Walkerai + Attackai

Рекомендуемые сообщения

Вечер добрый, есть заготовка AI для WalkerRoutes, грубо говоря траекторий ходьбы мобов/нпц:

public class WalkerAI extends DefaultAI

{

private int _routeIndex = 0;

private short _direction = 1;

private long _lastMove = 0;

 

public WalkerAI(NpcInstance actor)

{

super(actor);

setIntention(CtrlIntention.AI_INTENTION_ACTIVE);

}

 

@Override

protected boolean thinkActive()

{

WalkerRouteTemplate routeTemplate = getActor().getWalkerRouteTemplate();

 

if (routeTemplate == null)

return false;

 

boolean LINEAR = (routeTemplate.getRouteType() == RouteType.LINEAR);

boolean CYCLE = (routeTemplate.getRouteType() == RouteType.CYCLE);

boolean TELEPORT = (routeTemplate.getRouteType() == RouteType.TELEPORT);

 

if (routeTemplate.getIsRunning())

getActor().setRunning();

 

int pointsCount = routeTemplate.getPointsCount();

if (pointsCount <= 0)

return false;

 

Route point = null;

int oldIndex = _routeIndex;

 

if ((_routeIndex + _direction) >= pointsCount || (_routeIndex + _direction) < 0)

{

if (LINEAR)

{

_direction *= -1;

_routeIndex += _direction;

point = routeTemplate.getPoints().get(_routeIndex);

}

else if (CYCLE)

{

_direction = 1;

_routeIndex = 0;

point = routeTemplate.getPoints().get(_routeIndex);

}

else if (TELEPORT)

{

_direction = 1;

_routeIndex = 0;

point = routeTemplate.getPoints().get(_routeIndex);

}

}

else

{

_routeIndex += _direction;

point = routeTemplate.getPoints().get(_routeIndex);

}

 

Location nextLoc = point.getLoc();

long delay = (point.getDelay() <= 0) ? routeTemplate.getDelay() : point.getDelay();

 

if (_lastMove == 0)

{

_lastMove = System.currentTimeMillis() + delay;

_routeIndex = oldIndex;

return false;

}

 

else if (getActor().isMoving)

{

_routeIndex = oldIndex;

return false;

}

 

else if (System.currentTimeMillis() - _lastMove > delay)

{

if (TELEPORT & point.getLastPoint())

{

getActor().teleToLocation(nextLoc);

_lastMove = System.currentTimeMillis();

}

getActor().moveToLocation(nextLoc, 0, true);

_lastMove = System.currentTimeMillis();

}

 

return true;

}

}

 

 

 

Собственно, мне нужно чтобы мобы не только ходили, но при обнаружении игрока, еще и атаковали его.

Подскажите кто что думает.

 

Сборка овероподобная.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Написать метод и поставить вызов из thinkActive?

 

Из дефолтного АИ.

@Override
   protected boolean canAttackCharacter(Creature target)
   {
       return getActor().isAutoAttackable(target);
   }

  • Upvote 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Из дефолтного АИ.

@Override
protected boolean canAttackCharacter(Creature target)
{
return getActor().isAutoAttackable(target);
}

Честно говоря спорить с человеком с сертификатом кодера не хочется, но исходя из названия метода и в принципе его логики, он не начинает атаковать, а только проверяет можно-ли это сделать.
  • Upvote 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так, с этим,моб просто отвечает на агрессию, а чтоб он сам агрился?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может что-то типо

setIntention(AI_INTENTION_ATTACK, target);

Изменено пользователем LeKToR

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Собственно добавил

 

 

@Override

protected boolean createNewTask()

{

return defaultFightTask();

}

 

 

Моб отвечает если его атакуеш.

 

Теперь остался сабж.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

есстественно) суть в том что я ему , прилепил АИ волкера, он бежит и надо чтоб в процессе бега он агрился на чара)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

public class OrbisScout extends Fighter

{

private int _routeIndex = 0;

private short _direction = 1;

private long _lastMove = 0;

private NpcInstance actor;

 

public OrbisScout(NpcInstance actor)

{

super(actor);

setIntention(CtrlIntention.AI_INTENTION_ACTIVE);

}

 

@Override

protected boolean thinkActive()

{

WalkerRouteTemplate routeTemplate = getActor().getWalkerRouteTemplate();

 

if (routeTemplate == null)

return false;

 

boolean LINEAR = (routeTemplate.getRouteType() == RouteType.LINEAR);

boolean CYCLE = (routeTemplate.getRouteType() == RouteType.CYCLE);

boolean TELEPORT = (routeTemplate.getRouteType() == RouteType.TELEPORT);

 

if (routeTemplate.getIsRunning())

getActor().setRunning();

 

int pointsCount = routeTemplate.getPointsCount();

if (pointsCount <= 0)

return false;

 

Route point = null;

int oldIndex = _routeIndex;

 

if ((_routeIndex + _direction) >= pointsCount || (_routeIndex + _direction) < 0)

{

if (LINEAR)

{

_direction *= -1;

_routeIndex += _direction;

point = routeTemplate.getPoints().get(_routeIndex);

}

else if (CYCLE)

{

_direction = 1;

_routeIndex = 0;

point = routeTemplate.getPoints().get(_routeIndex);

}

else if (TELEPORT)

{

_direction = 1;

_routeIndex = 0;

point = routeTemplate.getPoints().get(_routeIndex);

}

}

else

{

_routeIndex += _direction;

point = routeTemplate.getPoints().get(_routeIndex);

}

 

Location nextLoc = point.getLoc();

long delay = (point.getDelay() <= 0) ? routeTemplate.getDelay() : point.getDelay();

 

if (_lastMove == 0)

{

_lastMove = System.currentTimeMillis() + delay;

_routeIndex = oldIndex;

return false;

}

 

else if (getActor().isMoving)

{

_routeIndex = oldIndex;

return false;

}

 

else if (System.currentTimeMillis() - _lastMove > delay)

{

if (TELEPORT & point.getLastPoint())

{

getActor().teleToLocation(nextLoc);

_lastMove = System.currentTimeMillis();

}

getActor().moveToLocation(nextLoc, 0, true);

_lastMove = System.currentTimeMillis();

}

 

return true;

}

 

@Override

protected boolean createNewTask()

{

return defaultFightTask();

}

 

@Override

public boolean checkAggression(Creature target)

{

return super.checkAggression(target);

}

 

@Override

public boolean isGlobalAI()

{

return true;

}

}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как вариант можешь когда моб должен идти к новой точке или когда прибежит на точку, делать проверку из KnownList'а типо если в радиусе N есть игроки или игрок бежать бить его. Заставить бить можно хоть напримую через присвоение АИ статуса атаки, либо через методы типо isAutoAttackable(target);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как вариант можешь когда моб должен идти к новой точке или когда прибежит на точку, делать проверку из KnownList'а типо если в радиусе N есть игроки или игрок бежать бить его. Заставить бить можно хоть напримую через присвоение АИ статуса атаки, либо через методы типо isAutoAttackable(target);

 

Меня прям аж упороло)

 

И присвоение интеншена атаки делал и авто атаку по обнаружению)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А Instance у твоего моба какой?

 

Просто в Instance есть ещё такой метод как isAttackeble() он переопределяется, возможно в Instance под которым у тебя моб бегает этот метод возвращает false и тогда мобу хоть на прямую говори чтобы он бил он бить не будет

Изменено пользователем Anon

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Instance стандартный MonsterInstance.

 

Собственно может внесет ясности:

Shot00014.bmp

 

Надо: Чтобы он бегал, агрился, отвечал на аттаку.

(координаты в АИ не вариант)

Изменено пользователем BrainEater

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я так понял у тебя он CtrlIntention.AI_INTENTION_ACTIVE занимается тем что бегает и с этим проблем нет.

Незнаю как там код устроен, но могу посоветовать сделай проверку переходит ли моб которого ты бьешь в другой АИ или только в активе и остается?

1. Сперва вычесли какой objectId моба, можешь сдлеать это через метод setTarget присав себе туда System.out.println(target.getObjectId())

2. узнав ид моба там где происходит setIntention в АИ делай проверку if (getActor().getObjectId() == ид который узнал) { System.out.println(Intention) }

вывод System.out.println(Intention) для того чтобы понять в какой АИ он переходит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Суть чуть в другом. Изначально, вводный у него Active, следовательно выполняется thinkActive(), который дает парсер координат для бега из WalkerRoutes.

Мне же надо, чтобы при обнаружении чара, вводное менялось на Attack, соответственно нужен thinkAttack().

 

Собственно надо лишь условие на смену Active->Attack и обратно, и само тело метода thinkAttack().

У меня немного логики не хватает для исполнения.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так в чем проблема после входа в метод thinkActive делай что я писал выше про поиск игроков через KnownList

что-то типо

 

for (L2PcInstance player : getActor().getKnowList().getKnownPlayerInRadius(2000))

{

setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);

}

 

реализовывай thinkAttack() а возврат из него делай что-то типо того же самого, только в обратном смысле если игроков нет в радиусе

if (getActor().getKnowList().getKnownPlayerInRadius(2000)).isEmpty())

{

setIntention(CtrlIntention.AI_INTENTION_ACTIVE);

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да мне только то что выше не в лыжеподобном виде бы и было бы щииикарно.

 

 

Creature player;

 

 

if (player.isPlayer() && player.isInRange(loc, 300))

{

_log.info("ATTACK");

changeIntention(CtrlIntention.AI_INTENTION_ATTACK, player, null);

//setIntention(CtrlIntention.AI_INTENTION_ATTACK);

}

 

 

 

@Override

protected void thinkAttack()

{

 

if (player.isPlayer() && !player.isInRange(loc, 300))

{

_log.info("ATTACK_OFF");

setIntention(CtrlIntention.AI_INTENTION_ACTIVE);

return;

}

 

super.thinkAttack();

}

 

В таком случае, аи не инициализируется вовсе

Изменено пользователем BrainEater

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А почему у тебя setIntention(CtrlIntention.AI_INTENTION_ATTACK); закоменчено? Оно вообще у тебя должно выглядеть как setIntention(CtrlIntention.AI_INTENTION_ATTACK, player, 1);

 

Насколько я осведомлен, последняя цыфра в этом setIntention записывает в агролист игрока, а параментр player нужен для того чтобы АИ знало кого ему атаковать

 

и что _log.info("ATTACK"); не выводит инфу что условия удовлетворяют?

а _log.info("ATTACK_OFF"); перемести до условий

вот так

 

 

@Override

protected void thinkAttack()

{

_log.info("ATTACK_OFF");

if (player.isPlayer() && !player.isInRange(loc, 300))

{

 

Чтобы убедиться что АИ сюда вообще попадает

  • Upvote 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проблема в том, что в thinkActive условия написанные мной не воспринимаются впринципе, выбивая невозможность присвоения АИ мобу

 

Поясню: нельзя ставить условия в которых будет содержаться булеан.

Изменено пользователем BrainEater

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация  

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...