BrainEater 217 Опубликовано 15 марта, 2013 Вечер добрый, есть заготовка 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; } } Собственно, мне нужно чтобы мобы не только ходили, но при обнаружении игрока, еще и атаковали его. Подскажите кто что думает. Сборка овероподобная. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Моветон 413 Опубликовано 15 марта, 2013 canAttackCharacter(target) 1 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
BrainEater 217 Опубликовано 15 марта, 2013 canAttackCharacter(target) Написать метод и поставить вызов из thinkActive? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Моветон 413 Опубликовано 15 марта, 2013 Написать метод и поставить вызов из thinkActive? Из дефолтного АИ. @Override protected boolean canAttackCharacter(Creature target) { return getActor().isAutoAttackable(target); } 1 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
xuser 122 Опубликовано 15 марта, 2013 Из дефолтного АИ. @Override protected boolean canAttackCharacter(Creature target) { return getActor().isAutoAttackable(target); } Честно говоря спорить с человеком с сертификатом кодера не хочется, но исходя из названия метода и в принципе его логики, он не начинает атаковать, а только проверяет можно-ли это сделать. 1 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
BrainEater 217 Опубликовано 15 марта, 2013 Так, с этим,моб просто отвечает на агрессию, а чтоб он сам агрился? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
xuser 122 Опубликовано 15 марта, 2013 (изменено) Может что-то типо setIntention(AI_INTENTION_ATTACK, target); Изменено 15 марта, 2013 пользователем LeKToR Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
BrainEater 217 Опубликовано 15 марта, 2013 Собственно добавил @Override protected boolean createNewTask() { return defaultFightTask(); } Моб отвечает если его атакуеш. Теперь остался сабж. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Моветон 413 Опубликовано 19 марта, 2013 checkAggression aggroRange 1 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
BrainEater 217 Опубликовано 19 марта, 2013 ставил, 0 реакции Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Моветон 413 Опубликовано 19 марта, 2013 ставил, 0 реакции У самого нпс указан aggroRange? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
BrainEater 217 Опубликовано 19 марта, 2013 есстественно) суть в том что я ему , прилепил АИ волкера, он бежит и надо чтоб в процессе бега он агрился на чара) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Моветон 413 Опубликовано 19 марта, 2013 АИ Гордона в помощь. Нужно лишь изменить checkAggression) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
BrainEater 217 Опубликовано 19 марта, 2013 да вот я и бьюсь с этим) но пока что одни НПЕ летят Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
BrainEater 217 Опубликовано 19 марта, 2013 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; } } Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Anon 2 Опубликовано 19 марта, 2013 Как вариант можешь когда моб должен идти к новой точке или когда прибежит на точку, делать проверку из KnownList'а типо если в радиусе N есть игроки или игрок бежать бить его. Заставить бить можно хоть напримую через присвоение АИ статуса атаки, либо через методы типо isAutoAttackable(target); Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
BrainEater 217 Опубликовано 19 марта, 2013 Как вариант можешь когда моб должен идти к новой точке или когда прибежит на точку, делать проверку из KnownList'а типо если в радиусе N есть игроки или игрок бежать бить его. Заставить бить можно хоть напримую через присвоение АИ статуса атаки, либо через методы типо isAutoAttackable(target); Меня прям аж упороло) И присвоение интеншена атаки делал и авто атаку по обнаружению) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Anon 2 Опубликовано 20 марта, 2013 (изменено) А Instance у твоего моба какой? Просто в Instance есть ещё такой метод как isAttackeble() он переопределяется, возможно в Instance под которым у тебя моб бегает этот метод возвращает false и тогда мобу хоть на прямую говори чтобы он бил он бить не будет Изменено 20 марта, 2013 пользователем Anon Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
BrainEater 217 Опубликовано 20 марта, 2013 (изменено) Instance стандартный MonsterInstance. Собственно может внесет ясности: Shot00014.bmp Надо: Чтобы он бегал, агрился, отвечал на аттаку. (координаты в АИ не вариант) Изменено 20 марта, 2013 пользователем BrainEater Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Anon 2 Опубликовано 20 марта, 2013 Я так понял у тебя он 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) для того чтобы понять в какой АИ он переходит. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
BrainEater 217 Опубликовано 20 марта, 2013 Суть чуть в другом. Изначально, вводный у него Active, следовательно выполняется thinkActive(), который дает парсер координат для бега из WalkerRoutes. Мне же надо, чтобы при обнаружении чара, вводное менялось на Attack, соответственно нужен thinkAttack(). Собственно надо лишь условие на смену Active->Attack и обратно, и само тело метода thinkAttack(). У меня немного логики не хватает для исполнения. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Anon 2 Опубликовано 20 марта, 2013 Так в чем проблема после входа в метод 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); } Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
BrainEater 217 Опубликовано 20 марта, 2013 (изменено) Да мне только то что выше не в лыжеподобном виде бы и было бы щииикарно. 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(); } В таком случае, аи не инициализируется вовсе Изменено 20 марта, 2013 пользователем BrainEater Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Anon 2 Опубликовано 20 марта, 2013 А почему у тебя 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)) { Чтобы убедиться что АИ сюда вообще попадает 1 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
BrainEater 217 Опубликовано 20 марта, 2013 (изменено) Проблема в том, что в thinkActive условия написанные мной не воспринимаются впринципе, выбивая невозможность присвоения АИ мобу Поясню: нельзя ставить условия в которых будет содержаться булеан. Изменено 20 марта, 2013 пользователем BrainEater Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты