Кастомный Next Target с регулируемой дальностью (interface+ядро)
Description
Первым делом, еще раз оговорюсь, что рациональней перепилить это дело под полноценный экшен, я же делал байпассом. Потому первым делом в ядре стоит запилить что-то такое:
if(command.startsWith("наш байпасс посылаемый с интерфейса")){ String[] idsh = command.substring(24).trim().split(" "); int dist = Integer.parseInt(idsh[0]); if (dist > 1200) { dist = 1200; } else if (dist < 400) { dist = 400; } List<L2Character> nextMob = new FastList<L2Character>(); for (L2Character players : player.getKnownList().getKnownCharactersInRadius(dist)) { if (players.isMonster() && players.isAttackable() && !players.isDead() && players.getCurrentHp()>=0 && players != player.getTarget()) { nextMob.add(players); } } int choice = Rnd.nextInt(nextMob.size()); if (choice > 0) { L2Character ftarget = nextMob.get(choice); player.setTarget(ftarget); player.sendPacket(new MyTargetSelected( ftarget.getObjectId(), 0)); StatusUpdate su = new StatusUpdate( ftarget.getObjectId()); su.addAttribute(StatusUpdate.CUR_HP, (int) ftarget.getStatus().getCurrentHp()); su.addAttribute(StatusUpdate.MAX_HP, ftarget.getMaxHp()); player.sendPacket(su); }
if(bypass.startsWith("_bbsntarget")){ StringTokenizer idsh = new StringTokenizer(bypass, " "); idsh.nextToken(); int dist = Integer.parseInt(idsh.nextToken()); if (dist > 1400) { dist = 1400; } else if (dist < 400) { dist = 400; } List<Creature> nextMob; nextMob = new LazyArrayList<Creature>(); for(Creature players : player.getAroundCharacters(dist, dist)) { if (players.isMonster() && !players.isDead() && players.getCurrentHp()>=0 && players != player.getTarget()) { nextMob.add(players); } } int choice = Rnd.get(nextMob.size()); if (nextMob.size() > 0) { Creature ftarget = nextMob.get(choice); player.setTarget(ftarget); player.sendPacket(new MyTargetSelected( ftarget.getObjectId(), 0)); player.sendPacket(ftarget.makeStatusUpdate(StatusUpdate.CUR_HP, StatusUpdate.MAX_HP)); } }
(!)Обратите внимание на мои условия, мне нужны были в таргете только монстры, для своих целей перепишите соответствующим образом. (да, у меня такой синтаксис что игроки это мобы, а мобы - это игроки, все в порядке) Так же заметьте, я ограничиваю максимальную дальность 1200, Вы можете этого не делать, либо задать свою. Я бы советовал ограничить максимальную дальность именно в ядре, ибо зная байпасс с интерфейса можно будет творить чудеса. Так же вопрос: нужно ли принудительно обновлять хп/мп таргета, если Вы уже шлете пакет MyTargetSelected? - На адекватных сборках может и нет, а вот у меня были проблемы пока так не сделал.
Так же Вы можете добавить проверку на видимость целей, что-то вроде:
GeoData.getInstance().canSeeTarget(activeChar, nextMob)
Почему я такую не добавил? Об этом в следующей кулстори расскажу.
Теперь в интерфейсе прикрутим в функцию OnLoad() следующее:
(здесь тоже довольно извращенная и чрезмерно нагроможденная конструкция, опять же скорее для наглядности, адекватно на это посмотреть и переписать нормально, а не копировать):
nrage(int(class'UIAPI_EDITBOX'.static.GetString("тут адрес нашего окна")));
Сама функция nrage:
function nrage(int valueX) { if ( valueX < 400) { NTrange = 400; } if ( valueX > 1200) { NTrange = 1200; } else { NTrange = valueX; } }
И наш отправляемый байпас:
RequestBypassToServer("наш байпасс посылаемый с интерфейса "$ NTrange);
Дальше (очень логично и последовательно, идя от конца к началу) оформим сам эдит бокс, с которого только что считывали дальность нашего некст таргета. Я его храню в другом классе, потому у Вас все может быть проще и красивее, в который раз повторюсь, что эта информация больше подходит для ознакомления, а не копипаста, хоть и будет работать и в таком виде.
И так, прежде всего:
var EditBoxHandle e_autoMacroRange; var MacroListWnd* script_mc; ..... e_autoMacroRange = GetEditBoxHandle("Ваше окно"); script_mc = MacroListWnd(GetScript("MacroListWnd")); *на всякий случай: это я тяну с другого класса скрипт, и напомню, что Вы можете без проблем обойтись и без этого
Я сохраняю настройки по клику кнопки, потому нужен хендлер OnClickButton, и в нем наша кнопка:
case "btnApply": OnApplyBtn(); break; .... сама функция кнопки (уже вне хендлера ,если что, наверное, это и так очевидно, но мне бы такая пометка жизнь спасти могла) function OnApplyBtn() { local int valueX if (e_autoMacroRange.GetString() != "") { valueX = int(e_autoMacroRange.GetString()); if (valueX >= 400 && valueX <= 1200) { SetINIInt("MacroSettings", "AutoMacroRange", valueX, "PatchSettings"); script_mc.nrage(valueX); } } }
Для загрузки наших данных о дальности нексттаргета из файла:
function LoadINISets() .... GetINIString("MacroSettings", "AutoMacroRange", valueS, "PatchSettings"); if (e_autoMacroRange.GetString() == "") { valueS = "750"; } e_autoMacroRange.SetString(valueS);
И вот сейчас был спорный момент, ибо раз уже замешано ядро - то зачем хранить эти данные в интерфейсе и почему бы не запихивать их куда-то на сервер сайде? Для себя я ответил: чтобы в эдитбоксе выводить актуальную дистанцию и не создавать лишних запросов в БД, а свой ответ Вы можете поискать сами, либо засунуть инфу на серверсайд.
- 4
- 2
Recommended Comments
There are no comments to display.